- Your Claude CLI is working correctly.
+ {cliAuthType === 'oauth'
+ ? 'Your Claude Code subscription is active and ready to use.'
+ : 'Your Claude CLI is working correctly.'}
+ Generate custom shell prompts that automatically sync with your app theme. Opt-in feature
+ that creates configs in .automaker/terminal/ without modifying your existing RC files.
+
+
+
+
+ {/* Enable Toggle */}
+
+
+
+
+ Create theme-synced shell configs in .automaker/terminal/
+
+ How it works: Custom configs are applied to new terminals only.
+ Your ~/.bashrc and ~/.zshrc are still loaded first. Close and reopen terminals to
+ see changes.
+
+
+
+ {/* Custom Prompt Toggle */}
+
+
+
+
+ Override default shell prompt with themed version
+
+ {promptThemePreset?.label ?? 'Oh My Posh theme'} uses the
+ oh-my-posh CLI for rendering. Ensure it's installed for the full theme.
+ Prompt format and segment toggles are ignored while an OMP theme is selected.
+
{isSelected && currentThinking === level && (
diff --git a/apps/ui/src/lib/agent-context-parser.ts b/apps/ui/src/lib/agent-context-parser.ts
index 8313e055..d6aa877a 100644
--- a/apps/ui/src/lib/agent-context-parser.ts
+++ b/apps/ui/src/lib/agent-context-parser.ts
@@ -27,13 +27,14 @@ export interface AgentTaskInfo {
/**
* Default model used by the feature executor
*/
-export const DEFAULT_MODEL = 'claude-opus-4-5-20251101';
+export const DEFAULT_MODEL = 'claude-opus-4-6';
/**
* Formats a model name for display
*/
export function formatModelName(model: string): string {
// Claude models
+ if (model.includes('opus-4-6')) return 'Opus 4.6';
if (model.includes('opus')) return 'Opus 4.5';
if (model.includes('sonnet')) return 'Sonnet 4.5';
if (model.includes('haiku')) return 'Haiku 4.5';
diff --git a/docs/llm-shared-packages.md b/docs/llm-shared-packages.md
index 9a81ad90..9f558c96 100644
--- a/docs/llm-shared-packages.md
+++ b/docs/llm-shared-packages.md
@@ -142,7 +142,7 @@ const modelId = resolveModelString('sonnet'); // → 'claude-sonnet-4-20250514'
- `haiku` → `claude-haiku-4-5` (fast, simple tasks)
- `sonnet` → `claude-sonnet-4-20250514` (balanced, recommended)
-- `opus` → `claude-opus-4-5-20251101` (maximum capability)
+- `opus` → `claude-opus-4-6` (maximum capability)
### @automaker/dependency-resolver
diff --git a/docs/server/providers.md b/docs/server/providers.md
index 757ecab1..4dae626e 100644
--- a/docs/server/providers.md
+++ b/docs/server/providers.md
@@ -175,7 +175,7 @@ Uses `@anthropic-ai/claude-agent-sdk` for direct SDK integration.
Routes models that:
-- Start with `"claude-"` (e.g., `"claude-opus-4-5-20251101"`)
+- Start with `"claude-"` (e.g., `"claude-opus-4-6"`)
- Are Claude aliases: `"opus"`, `"sonnet"`, `"haiku"`
#### Authentication
@@ -191,7 +191,7 @@ const provider = new ClaudeProvider();
const stream = provider.executeQuery({
prompt: 'What is 2+2?',
- model: 'claude-opus-4-5-20251101',
+ model: 'claude-opus-4-6',
cwd: '/project/path',
systemPrompt: 'You are a helpful assistant.',
maxTurns: 20,
@@ -701,7 +701,7 @@ Test provider interaction with services:
```typescript
describe('Provider Integration', () => {
it('should work with AgentService', async () => {
- const provider = ProviderFactory.getProviderForModel('claude-opus-4-5-20251101');
+ const provider = ProviderFactory.getProviderForModel('claude-opus-4-6');
// Test full workflow
});
diff --git a/docs/server/utilities.md b/docs/server/utilities.md
index b12e60a2..91d301bb 100644
--- a/docs/server/utilities.md
+++ b/docs/server/utilities.md
@@ -213,7 +213,7 @@ Model alias mapping for Claude models.
export const CLAUDE_MODEL_MAP: Record = {
haiku: 'claude-haiku-4-5',
sonnet: 'claude-sonnet-4-20250514',
- opus: 'claude-opus-4-5-20251101',
+ opus: 'claude-opus-4-6',
} as const;
```
@@ -223,7 +223,7 @@ Default models per provider.
```typescript
export const DEFAULT_MODELS = {
- claude: 'claude-opus-4-5-20251101',
+ claude: 'claude-opus-4-6',
openai: 'gpt-5.2',
} as const;
```
@@ -248,8 +248,8 @@ Resolve a model key/alias to a full model string.
import { resolveModelString, DEFAULT_MODELS } from '../lib/model-resolver.js';
resolveModelString('opus');
-// Returns: "claude-opus-4-5-20251101"
-// Logs: "[ModelResolver] Resolved model alias: "opus" -> "claude-opus-4-5-20251101""
+// Returns: "claude-opus-4-6"
+// Logs: "[ModelResolver] Resolved model alias: "opus" -> "claude-opus-4-6""
resolveModelString('gpt-5.2');
// Returns: "gpt-5.2"
@@ -260,8 +260,8 @@ resolveModelString('claude-sonnet-4-20250514');
// Logs: "[ModelResolver] Using full Claude model string: claude-sonnet-4-20250514"
resolveModelString('invalid-model');
-// Returns: "claude-opus-4-5-20251101"
-// Logs: "[ModelResolver] Unknown model key "invalid-model", using default: "claude-opus-4-5-20251101""
+// Returns: "claude-opus-4-6"
+// Logs: "[ModelResolver] Unknown model key "invalid-model", using default: "claude-opus-4-6""
```
---
diff --git a/libs/model-resolver/README.md b/libs/model-resolver/README.md
index 50bdf4f9..ce5aa3ce 100644
--- a/libs/model-resolver/README.md
+++ b/libs/model-resolver/README.md
@@ -30,15 +30,15 @@ const model2 = resolveModelString('haiku');
// Returns: 'claude-haiku-4-5'
const model3 = resolveModelString('opus');
-// Returns: 'claude-opus-4-5-20251101'
+// Returns: 'claude-opus-4-6'
// Use with custom default
const model4 = resolveModelString(undefined, 'claude-sonnet-4-20250514');
// Returns: 'claude-sonnet-4-20250514' (default)
// Direct model ID passthrough
-const model5 = resolveModelString('claude-opus-4-5-20251101');
-// Returns: 'claude-opus-4-5-20251101' (unchanged)
+const model5 = resolveModelString('claude-opus-4-6');
+// Returns: 'claude-opus-4-6' (unchanged)
```
### Get Effective Model
@@ -72,7 +72,7 @@ console.log(DEFAULT_MODELS.chat); // 'claude-sonnet-4-20250514'
// Model alias mappings
console.log(CLAUDE_MODEL_MAP.haiku); // 'claude-haiku-4-5'
console.log(CLAUDE_MODEL_MAP.sonnet); // 'claude-sonnet-4-20250514'
-console.log(CLAUDE_MODEL_MAP.opus); // 'claude-opus-4-5-20251101'
+console.log(CLAUDE_MODEL_MAP.opus); // 'claude-opus-4-6'
```
## Usage Example
@@ -103,7 +103,7 @@ const feature: Feature = {
};
prepareFeatureExecution(feature);
-// Output: Executing feature with model: claude-opus-4-5-20251101
+// Output: Executing feature with model: claude-opus-4-6
```
## Supported Models
@@ -112,7 +112,7 @@ prepareFeatureExecution(feature);
- `haiku` → `claude-haiku-4-5`
- `sonnet` → `claude-sonnet-4-20250514`
-- `opus` → `claude-opus-4-5-20251101`
+- `opus` → `claude-opus-4-6`
### Model Selection Guide
diff --git a/libs/model-resolver/tests/resolver.test.ts b/libs/model-resolver/tests/resolver.test.ts
index 84623b5b..7b6af623 100644
--- a/libs/model-resolver/tests/resolver.test.ts
+++ b/libs/model-resolver/tests/resolver.test.ts
@@ -484,12 +484,12 @@ describe('model-resolver', () => {
it('should handle full Claude model string in entry', () => {
const entry: PhaseModelEntry = {
- model: 'claude-opus-4-5-20251101',
+ model: 'claude-opus-4-6',
thinkingLevel: 'high',
};
const result = resolvePhaseModel(entry);
- expect(result.model).toBe('claude-opus-4-5-20251101');
+ expect(result.model).toBe('claude-opus-4-6');
expect(result.thinkingLevel).toBe('high');
});
});
diff --git a/libs/types/src/index.ts b/libs/types/src/index.ts
index d6d305fe..e9193327 100644
--- a/libs/types/src/index.ts
+++ b/libs/types/src/index.ts
@@ -196,6 +196,8 @@ export {
PROJECT_SETTINGS_VERSION,
THINKING_TOKEN_BUDGET,
getThinkingTokenBudget,
+ isAdaptiveThinkingModel,
+ getThinkingLevelsForModel,
// Event hook constants
EVENT_HOOK_TRIGGER_LABELS,
// Claude-compatible provider templates (new)
diff --git a/libs/types/src/model-display.ts b/libs/types/src/model-display.ts
index 08eaf208..f8a53e8b 100644
--- a/libs/types/src/model-display.ts
+++ b/libs/types/src/model-display.ts
@@ -149,6 +149,7 @@ export const THINKING_LEVELS: ThinkingLevelOption[] = [
{ id: 'medium', label: 'Medium' },
{ id: 'high', label: 'High' },
{ id: 'ultrathink', label: 'Ultrathink' },
+ { id: 'adaptive', label: 'Adaptive' },
];
/**
@@ -162,6 +163,7 @@ export const THINKING_LEVEL_LABELS: Record = {
medium: 'Med',
high: 'High',
ultrathink: 'Ultra',
+ adaptive: 'Adaptive',
};
/**
diff --git a/libs/types/src/model.ts b/libs/types/src/model.ts
index b6b90da9..2d540cc0 100644
--- a/libs/types/src/model.ts
+++ b/libs/types/src/model.ts
@@ -18,7 +18,7 @@ export type ClaudeCanonicalId = 'claude-haiku' | 'claude-sonnet' | 'claude-opus'
export const CLAUDE_CANONICAL_MAP: Record = {
'claude-haiku': 'claude-haiku-4-5-20251001',
'claude-sonnet': 'claude-sonnet-4-5-20250929',
- 'claude-opus': 'claude-opus-4-5-20251101',
+ 'claude-opus': 'claude-opus-4-6',
} as const;
/**
@@ -29,7 +29,7 @@ export const CLAUDE_CANONICAL_MAP: Record = {
export const CLAUDE_MODEL_MAP: Record = {
haiku: 'claude-haiku-4-5-20251001',
sonnet: 'claude-sonnet-4-5-20250929',
- opus: 'claude-opus-4-5-20251101',
+ opus: 'claude-opus-4-6',
} as const;
/**
@@ -99,7 +99,7 @@ export function getAllCodexModelIds(): CodexModelId[] {
* Uses canonical prefixed IDs for consistent routing.
*/
export const DEFAULT_MODELS = {
- claude: 'claude-opus-4-5-20251101',
+ claude: 'claude-opus-4-6',
cursor: 'cursor-auto', // Cursor's recommended default (with prefix)
codex: CODEX_MODEL_MAP.gpt52Codex, // GPT-5.2-Codex is the most advanced agentic coding model
} as const;
diff --git a/libs/types/src/settings.ts b/libs/types/src/settings.ts
index eb53564d..06743faa 100644
--- a/libs/types/src/settings.ts
+++ b/libs/types/src/settings.ts
@@ -213,7 +213,7 @@ export type PlanningMode = 'skip' | 'lite' | 'spec' | 'full';
export type ServerLogLevel = 'error' | 'warn' | 'info' | 'debug';
/** ThinkingLevel - Extended thinking levels for Claude models (reasoning intensity) */
-export type ThinkingLevel = 'none' | 'low' | 'medium' | 'high' | 'ultrathink';
+export type ThinkingLevel = 'none' | 'low' | 'medium' | 'high' | 'ultrathink' | 'adaptive';
/**
* SidebarStyle - Sidebar layout style options
@@ -237,6 +237,7 @@ export const THINKING_TOKEN_BUDGET: Record =
medium: 10000, // Light reasoning
high: 16000, // Complex tasks (recommended starting point)
ultrathink: 32000, // Maximum safe (above this risks timeouts)
+ adaptive: undefined, // Adaptive thinking (Opus 4.6) - SDK handles token allocation
};
/**
@@ -247,6 +248,26 @@ export function getThinkingTokenBudget(level: ThinkingLevel | undefined): number
return THINKING_TOKEN_BUDGET[level];
}
+/**
+ * Check if a model uses adaptive thinking (Opus 4.6+)
+ * Adaptive thinking models let the SDK decide token allocation automatically.
+ */
+export function isAdaptiveThinkingModel(model: string): boolean {
+ return model.includes('opus-4-6') || model === 'claude-opus';
+}
+
+/**
+ * Get the available thinking levels for a given model.
+ * - Opus 4.6: Only 'none' and 'adaptive' (SDK handles token allocation)
+ * - Others: Full range of manual thinking levels
+ */
+export function getThinkingLevelsForModel(model: string): ThinkingLevel[] {
+ if (isAdaptiveThinkingModel(model)) {
+ return ['none', 'adaptive'];
+ }
+ return ['none', 'low', 'medium', 'high', 'ultrathink'];
+}
+
/** ModelProvider - AI model provider for credentials and API key management */
export type ModelProvider = 'claude' | 'cursor' | 'codex' | 'opencode' | 'gemini' | 'copilot';
diff --git a/package-lock.json b/package-lock.json
index 0649982d..8804b479 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -35,7 +35,7 @@
"version": "0.13.0",
"license": "SEE LICENSE IN LICENSE",
"dependencies": {
- "@anthropic-ai/claude-agent-sdk": "0.1.76",
+ "@anthropic-ai/claude-agent-sdk": "0.2.32",
"@automaker/dependency-resolver": "1.0.0",
"@automaker/git-utils": "1.0.0",
"@automaker/model-resolver": "1.0.0",
@@ -657,9 +657,9 @@
}
},
"node_modules/@anthropic-ai/claude-agent-sdk": {
- "version": "0.1.76",
- "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.1.76.tgz",
- "integrity": "sha512-s7RvpXoFaLXLG7A1cJBAPD8ilwOhhc/12fb5mJXRuD561o4FmPtQ+WRfuy9akMmrFRfLsKv8Ornw3ClGAPL2fw==",
+ "version": "0.2.32",
+ "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.2.32.tgz",
+ "integrity": "sha512-8AtsSx/M9jxd0ihS08eqa7VireTEuwQy0i1+6ZJX93LECT6Svlf47dPJiAm7JB+BhVMmwTfQeS6x1akIcCfvbQ==",
"license": "SEE LICENSE IN README.md",
"engines": {
"node": ">=18.0.0"
@@ -675,7 +675,7 @@
"@img/sharp-win32-x64": "^0.33.5"
},
"peerDependencies": {
- "zod": "^3.24.1 || ^4.0.0"
+ "zod": "^4.0.0"
}
},
"node_modules/@automaker/dependency-resolver": {
From f97453484fc7f484cfeefcde2df1ee52fac3180b Mon Sep 17 00:00:00 2001
From: Kacper
Date: Thu, 5 Feb 2026 23:05:19 +0100
Subject: [PATCH 15/21] feat: enhance adaptive thinking model support and
update UI components
- Added `isAdaptiveThinkingModel` utility to improve model identification logic in the AddFeatureDialog.
- Updated the ThinkingLevelSelector to conditionally display information based on available thinking levels.
- Enhanced model name formatting in agent-context-parser to include 'GPT-5.3 Codex' for better clarity.
These changes improve the user experience by refining model handling and UI feedback related to adaptive thinking capabilities.
---
.../views/board-view/dialogs/add-feature-dialog.tsx | 5 ++---
.../views/board-view/shared/thinking-level-selector.tsx | 2 +-
apps/ui/src/lib/agent-context-parser.ts | 1 +
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/apps/ui/src/components/views/board-view/dialogs/add-feature-dialog.tsx b/apps/ui/src/components/views/board-view/dialogs/add-feature-dialog.tsx
index 2dbf0808..a816204f 100644
--- a/apps/ui/src/components/views/board-view/dialogs/add-feature-dialog.tsx
+++ b/apps/ui/src/components/views/board-view/dialogs/add-feature-dialog.tsx
@@ -28,7 +28,7 @@ import { cn } from '@/lib/utils';
import { modelSupportsThinking } from '@/lib/utils';
import { useAppStore, ThinkingLevel, FeatureImage, PlanningMode, Feature } from '@/store/app-store';
import type { ReasoningEffort, PhaseModelEntry, AgentModel } from '@automaker/types';
-import { supportsReasoningEffort } from '@automaker/types';
+import { supportsReasoningEffort, isAdaptiveThinkingModel } from '@automaker/types';
import {
PrioritySelector,
WorkModeSelector,
@@ -266,8 +266,7 @@ export function AddFeatureDialog({
const handleModelChange = (entry: PhaseModelEntry) => {
// Normalize thinking level when switching between adaptive and non-adaptive models
const isNewModelAdaptive =
- entry.model === 'claude-opus' ||
- (typeof entry.model === 'string' && entry.model.includes('opus-4-6'));
+ typeof entry.model === 'string' && isAdaptiveThinkingModel(entry.model);
const currentLevel = entry.thinkingLevel || 'none';
if (isNewModelAdaptive && currentLevel !== 'none' && currentLevel !== 'adaptive') {
diff --git a/apps/ui/src/components/views/board-view/shared/thinking-level-selector.tsx b/apps/ui/src/components/views/board-view/shared/thinking-level-selector.tsx
index 3e111a31..c74b3e9a 100644
--- a/apps/ui/src/components/views/board-view/shared/thinking-level-selector.tsx
+++ b/apps/ui/src/components/views/board-view/shared/thinking-level-selector.tsx
@@ -46,7 +46,7 @@ export function ThinkingLevelSelector({
))}
- {model && getThinkingLevelsForModel(model).includes('adaptive')
+ {levels.includes('adaptive')
? 'Adaptive thinking lets the model decide how much reasoning to use.'
: 'Higher levels give more time to reason through complex problems.'}
diff --git a/apps/ui/src/lib/agent-context-parser.ts b/apps/ui/src/lib/agent-context-parser.ts
index d6aa877a..996b397b 100644
--- a/apps/ui/src/lib/agent-context-parser.ts
+++ b/apps/ui/src/lib/agent-context-parser.ts
@@ -40,6 +40,7 @@ export function formatModelName(model: string): string {
if (model.includes('haiku')) return 'Haiku 4.5';
// Codex/GPT models - specific formatting
+ if (model === 'codex-gpt-5.3-codex') return 'GPT-5.3 Codex';
if (model === 'codex-gpt-5.2-codex') return 'GPT-5.2 Codex';
if (model === 'codex-gpt-5.2') return 'GPT-5.2';
if (model === 'codex-gpt-5.1-codex-max') return 'GPT-5.1 Max';
From 220c8e4ddf8a31adb68b831c63590e8cb742d08a Mon Sep 17 00:00:00 2001
From: Kacper
Date: Thu, 5 Feb 2026 23:19:31 +0100
Subject: [PATCH 16/21] feat: add 'dev-server:url-detected' event type to
EventType
- Introduced a new event type 'dev-server:url-detected' to enhance event handling for the development server.
- This addition allows for better tracking and response to URL detection during server operations.
These changes improve the event system's capability to manage server-related events effectively.
---
libs/types/src/event.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/libs/types/src/event.ts b/libs/types/src/event.ts
index 281f88d8..d11bfd07 100644
--- a/libs/types/src/event.ts
+++ b/libs/types/src/event.ts
@@ -46,6 +46,7 @@ export type EventType =
| 'dev-server:started'
| 'dev-server:output'
| 'dev-server:stopped'
+ | 'dev-server:url-detected'
| 'test-runner:started'
| 'test-runner:progress'
| 'test-runner:output'
From 3563dd55dad4bdbd45e73dd5a90d90da3684864b Mon Sep 17 00:00:00 2001
From: DhanushSantosh
Date: Sun, 8 Feb 2026 16:40:55 +0530
Subject: [PATCH 17/21] fix: recover interrupted features and allow branch
switch with untracked files
---
.../routes/worktree/routes/switch-branch.ts | 35 +++---
apps/server/src/services/auto-mode-service.ts | 8 +-
.../routes/worktree/switch-branch.test.ts | 106 ++++++++++++++++++
.../unit/services/auto-mode-service.test.ts | 75 +++++++++++++
4 files changed, 203 insertions(+), 21 deletions(-)
create mode 100644 apps/server/tests/unit/routes/worktree/switch-branch.test.ts
diff --git a/apps/server/src/routes/worktree/routes/switch-branch.ts b/apps/server/src/routes/worktree/routes/switch-branch.ts
index d087341b..63be752b 100644
--- a/apps/server/src/routes/worktree/routes/switch-branch.ts
+++ b/apps/server/src/routes/worktree/routes/switch-branch.ts
@@ -16,6 +16,21 @@ import { getErrorMessage, logError } from '../common.js';
const execAsync = promisify(exec);
+function isUntrackedLine(line: string): boolean {
+ return line.startsWith('?? ');
+}
+
+function isExcludedWorktreeLine(line: string): boolean {
+ return line.includes('.worktrees/') || line.endsWith('.worktrees');
+}
+
+function isBlockingChangeLine(line: string): boolean {
+ if (!line.trim()) return false;
+ if (isExcludedWorktreeLine(line)) return false;
+ if (isUntrackedLine(line)) return false;
+ return true;
+}
+
/**
* Check if there are uncommitted changes in the working directory
* Excludes .worktrees/ directory which is created by automaker
@@ -23,15 +38,7 @@ const execAsync = promisify(exec);
async function hasUncommittedChanges(cwd: string): Promise {
try {
const { stdout } = await execAsync('git status --porcelain', { cwd });
- const lines = stdout
- .trim()
- .split('\n')
- .filter((line) => {
- if (!line.trim()) return false;
- // Exclude .worktrees/ directory (created by automaker)
- if (line.includes('.worktrees/') || line.endsWith('.worktrees')) return false;
- return true;
- });
+ const lines = stdout.trim().split('\n').filter(isBlockingChangeLine);
return lines.length > 0;
} catch {
return false;
@@ -45,15 +52,7 @@ async function hasUncommittedChanges(cwd: string): Promise {
async function getChangesSummary(cwd: string): Promise {
try {
const { stdout } = await execAsync('git status --short', { cwd });
- const lines = stdout
- .trim()
- .split('\n')
- .filter((line) => {
- if (!line.trim()) return false;
- // Exclude .worktrees/ directory
- if (line.includes('.worktrees/') || line.endsWith('.worktrees')) return false;
- return true;
- });
+ const lines = stdout.trim().split('\n').filter(isBlockingChangeLine);
if (lines.length === 0) return '';
if (lines.length <= 5) return lines.join(', ');
return `${lines.slice(0, 5).join(', ')} and ${lines.length - 5} more files`;
diff --git a/apps/server/src/services/auto-mode-service.ts b/apps/server/src/services/auto-mode-service.ts
index 0c7416b9..ffb87591 100644
--- a/apps/server/src/services/auto-mode-service.ts
+++ b/apps/server/src/services/auto-mode-service.ts
@@ -3718,13 +3718,14 @@ Format your response as a structured markdown document.`;
// Recovery cases:
// 1. Standard pending/ready/backlog statuses
// 2. Features with approved plans that have incomplete tasks (crash recovery)
- // 3. Features stuck in 'in_progress' status (crash recovery)
+ // 3. Features stuck in 'in_progress' or 'interrupted' status (crash recovery)
// 4. Features with 'generating' planSpec status (spec generation was interrupted)
const needsRecovery =
feature.status === 'pending' ||
feature.status === 'ready' ||
feature.status === 'backlog' ||
feature.status === 'in_progress' || // Recover features that were in progress when server crashed
+ feature.status === 'interrupted' || // Recover features explicitly marked interrupted on shutdown
(feature.planSpec?.status === 'approved' &&
(feature.planSpec.tasksCompleted ?? 0) < (feature.planSpec.tasksTotal ?? 0)) ||
feature.planSpec?.status === 'generating'; // Recover interrupted spec generation
@@ -3764,7 +3765,7 @@ Format your response as a structured markdown document.`;
const worktreeDesc = branchName ? `worktree ${branchName}` : 'main worktree';
logger.info(
- `[loadPendingFeatures] Found ${allFeatures.length} total features, ${pendingFeatures.length} candidates (pending/ready/backlog/in_progress/approved_with_pending_tasks/generating) for ${worktreeDesc}`
+ `[loadPendingFeatures] Found ${allFeatures.length} total features, ${pendingFeatures.length} candidates (pending/ready/backlog/in_progress/interrupted/approved_with_pending_tasks/generating) for ${worktreeDesc}`
);
if (pendingFeatures.length === 0) {
@@ -5536,9 +5537,10 @@ This mock response was generated because AUTOMAKER_MOCK_AGENT=true was set.
continue;
}
- // Check if feature was interrupted (in_progress or pipeline_*)
+ // Check if feature was interrupted (in_progress/interrupted or pipeline_*)
if (
feature.status === 'in_progress' ||
+ feature.status === 'interrupted' ||
(feature.status && feature.status.startsWith('pipeline_'))
) {
// Check if context (agent-output.md) exists
diff --git a/apps/server/tests/unit/routes/worktree/switch-branch.test.ts b/apps/server/tests/unit/routes/worktree/switch-branch.test.ts
new file mode 100644
index 00000000..2cd868c6
--- /dev/null
+++ b/apps/server/tests/unit/routes/worktree/switch-branch.test.ts
@@ -0,0 +1,106 @@
+import { describe, it, expect, vi, beforeEach, type Mock } from 'vitest';
+import type { Request, Response } from 'express';
+import { createMockExpressContext } from '../../../utils/mocks.js';
+
+vi.mock('child_process', async (importOriginal) => {
+ const actual = await importOriginal();
+ return {
+ ...actual,
+ exec: vi.fn(),
+ };
+});
+
+vi.mock('util', async (importOriginal) => {
+ const actual = await importOriginal();
+ return {
+ ...actual,
+ promisify: (fn: unknown) => fn,
+ };
+});
+
+import { exec } from 'child_process';
+import { createSwitchBranchHandler } from '@/routes/worktree/routes/switch-branch.js';
+
+const mockExec = exec as Mock;
+
+describe('switch-branch route', () => {
+ let req: Request;
+ let res: Response;
+
+ beforeEach(() => {
+ vi.clearAllMocks();
+ const context = createMockExpressContext();
+ req = context.req;
+ res = context.res;
+ });
+
+ it('should allow switching when only untracked files exist', async () => {
+ req.body = {
+ worktreePath: '/repo/path',
+ branchName: 'feature/test',
+ };
+
+ mockExec.mockImplementation(async (command: string) => {
+ if (command === 'git rev-parse --abbrev-ref HEAD') {
+ return { stdout: 'main\n', stderr: '' };
+ }
+ if (command === 'git rev-parse --verify feature/test') {
+ return { stdout: 'abc123\n', stderr: '' };
+ }
+ if (command === 'git status --porcelain') {
+ return { stdout: '?? .automaker/\n?? notes.txt\n', stderr: '' };
+ }
+ if (command === 'git checkout "feature/test"') {
+ return { stdout: '', stderr: '' };
+ }
+ return { stdout: '', stderr: '' };
+ });
+
+ const handler = createSwitchBranchHandler();
+ await handler(req, res);
+
+ expect(res.json).toHaveBeenCalledWith({
+ success: true,
+ result: {
+ previousBranch: 'main',
+ currentBranch: 'feature/test',
+ message: "Switched to branch 'feature/test'",
+ },
+ });
+ expect(mockExec).toHaveBeenCalledWith('git checkout "feature/test"', { cwd: '/repo/path' });
+ });
+
+ it('should block switching when tracked files are modified', async () => {
+ req.body = {
+ worktreePath: '/repo/path',
+ branchName: 'feature/test',
+ };
+
+ mockExec.mockImplementation(async (command: string) => {
+ if (command === 'git rev-parse --abbrev-ref HEAD') {
+ return { stdout: 'main\n', stderr: '' };
+ }
+ if (command === 'git rev-parse --verify feature/test') {
+ return { stdout: 'abc123\n', stderr: '' };
+ }
+ if (command === 'git status --porcelain') {
+ return { stdout: ' M src/index.ts\n?? notes.txt\n', stderr: '' };
+ }
+ if (command === 'git status --short') {
+ return { stdout: ' M src/index.ts\n?? notes.txt\n', stderr: '' };
+ }
+ return { stdout: '', stderr: '' };
+ });
+
+ const handler = createSwitchBranchHandler();
+ await handler(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(400);
+ expect(res.json).toHaveBeenCalledWith({
+ success: false,
+ error:
+ 'Cannot switch branches: you have uncommitted changes (M src/index.ts). Please commit your changes first.',
+ code: 'UNCOMMITTED_CHANGES',
+ });
+ });
+});
diff --git a/apps/server/tests/unit/services/auto-mode-service.test.ts b/apps/server/tests/unit/services/auto-mode-service.test.ts
index 7f3f9af0..a8489033 100644
--- a/apps/server/tests/unit/services/auto-mode-service.test.ts
+++ b/apps/server/tests/unit/services/auto-mode-service.test.ts
@@ -1,6 +1,9 @@
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { AutoModeService } from '@/services/auto-mode-service.js';
import type { Feature } from '@automaker/types';
+import fs from 'fs/promises';
+import os from 'os';
+import path from 'path';
describe('auto-mode-service.ts', () => {
let service: AutoModeService;
@@ -842,4 +845,76 @@ describe('auto-mode-service.ts', () => {
expect(service.isFeatureRunning('feature-3')).toBe(false);
});
});
+
+ describe('interrupted recovery', () => {
+ async function createFeatureFixture(
+ projectPath: string,
+ feature: Partial & Pick
+ ): Promise {
+ const featureDir = path.join(projectPath, '.automaker', 'features', feature.id);
+ await fs.mkdir(featureDir, { recursive: true });
+ await fs.writeFile(
+ path.join(featureDir, 'feature.json'),
+ JSON.stringify(
+ {
+ title: 'Feature',
+ description: 'Feature description',
+ category: 'implementation',
+ status: 'backlog',
+ ...feature,
+ },
+ null,
+ 2
+ )
+ );
+ return featureDir;
+ }
+
+ it('should resume features marked as interrupted after restart', async () => {
+ const projectPath = await fs.mkdtemp(path.join(os.tmpdir(), 'automaker-resume-'));
+ try {
+ const featureDir = await createFeatureFixture(projectPath, {
+ id: 'feature-interrupted',
+ status: 'interrupted',
+ });
+ await fs.writeFile(path.join(featureDir, 'agent-output.md'), 'partial progress');
+ await createFeatureFixture(projectPath, {
+ id: 'feature-complete',
+ status: 'completed',
+ });
+
+ const resumeFeatureMock = vi.fn().mockResolvedValue(undefined);
+ (service as any).resumeFeature = resumeFeatureMock;
+
+ await (service as any).resumeInterruptedFeatures(projectPath);
+
+ expect(resumeFeatureMock).toHaveBeenCalledTimes(1);
+ expect(resumeFeatureMock).toHaveBeenCalledWith(projectPath, 'feature-interrupted', true);
+ } finally {
+ await fs.rm(projectPath, { recursive: true, force: true });
+ }
+ });
+
+ it('should include interrupted features in pending recovery candidates', async () => {
+ const projectPath = await fs.mkdtemp(path.join(os.tmpdir(), 'automaker-pending-'));
+ try {
+ await createFeatureFixture(projectPath, {
+ id: 'feature-interrupted',
+ status: 'interrupted',
+ });
+ await createFeatureFixture(projectPath, {
+ id: 'feature-waiting-approval',
+ status: 'waiting_approval',
+ });
+
+ const pendingFeatures = await (service as any).loadPendingFeatures(projectPath, null);
+ const pendingIds = pendingFeatures.map((feature: Feature) => feature.id);
+
+ expect(pendingIds).toContain('feature-interrupted');
+ expect(pendingIds).not.toContain('feature-waiting-approval');
+ } finally {
+ await fs.rm(projectPath, { recursive: true, force: true });
+ }
+ });
+ });
});
From 9c304eeec3369bf4b6859fd791b54e874c54b39e Mon Sep 17 00:00:00 2001
From: webdevcody
Date: Fri, 13 Feb 2026 13:46:32 -0500
Subject: [PATCH 18/21] chore: update project status and licensing information
- Replace the Automaker License Agreement with a simplified project status section in the README, indicating that the project is no longer actively maintained.
- Update the LICENSE file to reflect the new MIT License.
- Add license information to package.json for clarity.
---
LICENSE | 158 +++++++--------------------------------------------
README.md | 30 +++-------
package.json | 1 +
3 files changed, 32 insertions(+), 157 deletions(-)
diff --git a/LICENSE b/LICENSE
index c7a1fe44..e388c0a7 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,141 +1,27 @@
-AUTOMAKER LICENSE AGREEMENT
+## Project Status
-This License Agreement ("Agreement") is entered into between you ("Licensee") and the copyright holders of Automaker ("Licensor"). By using, copying, modifying, downloading, cloning, or distributing the Software (as defined below), you agree to be bound by the terms of this Agreement.
-
-1. DEFINITIONS
-
-"Software" means the Automaker software, including all source code, object code, documentation, and related materials.
-
-"Generated Files" means files created by the Software during normal operation to store internal state, configuration, or working data, including but not limited to app_spec.txt, feature.json, and similar files generated by the Software. Generated Files are not considered part of the Software for the purposes of this license and are not subject to the restrictions herein.
-
-"Derivative Work" means any work that is based on, derived from, or incorporates the Software or any substantial portion of it, including but not limited to modifications, forks, adaptations, translations, or any altered version of the Software.
-
-"Monetization" means any activity that generates revenue, income, or commercial benefit from the Software itself or any Derivative Work, including but not limited to:
-
-- Reselling, redistributing, or sublicensing the Software, any Derivative Work, or any substantial portion thereof
-- Including the Software, any Derivative Work, or substantial portions thereof in a product or service that you sell or distribute
-- Offering the Software, any Derivative Work, or substantial portions thereof as a standalone product or service for sale
-- Hosting the Software or any Derivative Work as a service (whether free or paid) for use by others, including cloud hosting, Software-as-a-Service (SaaS), or any other form of hosted access for third parties
-- Extracting, reselling, redistributing, or sublicensing any prompts, context, or other instructional content bundled within the Software
-- Creating, distributing, or selling modified versions, forks, or Derivative Works of the Software
-
-Monetization does NOT include:
-
-- Using the Software internally within your organization, regardless of whether your organization is for-profit
-- Using the Software to build products or services that generate revenue, as long as you are not reselling or redistributing the Software itself
-- Using the Software to provide services for which fees are charged, as long as the Software itself is not being resold or redistributed
-- Hosting the Software anywhere for personal use by a single developer, as long as the Software is not made accessible to others
-
-"Core Contributors" means the following individuals who are granted perpetual, royalty-free licenses:
-
-- Cody Seibert (webdevcody)
-- SuperComboGamer (SCG)
-- Kacper Lachowicz (Shironex, Shirone)
-- Ben Scott (trueheads)
-
-2. GRANT OF LICENSE
-
-Subject to the terms and conditions of this Agreement, Licensor hereby grants to Licensee a non-exclusive, non-transferable license to use, copy, modify, and distribute the Software, provided that:
-
-a) Licensee may freely clone, install, and use the Software locally or within an organization for the purpose of building, developing, and maintaining other products, software, or services. There are no restrictions on the products you build _using_ the Software.
-
-b) Licensee may run the Software on personal or organizational infrastructure for internal use.
-
-c) Core Contributors are each individually granted a perpetual, worldwide, royalty-free, non-exclusive license to use, copy, modify, distribute, and sublicense the Software for any purpose, including Monetization, without payment of any fees or royalties. Each Core Contributor may exercise these rights independently and does not require permission, consent, or approval from any other Core Contributor to Monetize the Software in any way they see fit.
-
-d) Commercial licenses for the Software may be discussed and issued to external parties or companies seeking to use the Software for financial gain or Monetization purposes. Core Contributors already have full rights under section 2(c) and do not require commercial licenses. Any commercial license issued to external parties shall require a unanimous vote by all Core Contributors and shall be granted in writing and signed by all Core Contributors.
-
-e) The list of individuals defined as "Core Contributors" in Section 1 shall be amended to reflect any revocation or reinstatement of status made under this section.
-
-3. RESTRICTIONS
-
-Licensee may NOT:
-
-- Engage in any Monetization of the Software or any Derivative Work without explicit written permission from all Core Contributors
-- Resell, redistribute, or sublicense the Software, any Derivative Work, or any substantial portion thereof
-- Create, distribute, or sell modified versions, forks, or Derivative Works of the Software for any commercial purpose
-- Include the Software, any Derivative Work, or substantial portions thereof in a product or service that you sell or distribute
-- Offer the Software, any Derivative Work, or substantial portions thereof as a standalone product or service for sale
-- Extract, resell, redistribute, or sublicense any prompts, context, or other instructional content bundled within the Software
-- Host the Software or any Derivative Work as a service (whether free or paid) for use by others (except Core Contributors)
-- Remove or alter any copyright notices or license terms
-- Use the Software in any manner that violates applicable laws or regulations
-
-Licensee MAY:
-
-- Use the Software internally within their organization (commercial or non-profit)
-- Use the Software to build other commercial products (products that do NOT contain the Software or Derivative Works)
-- Modify the Software for internal use within their organization (commercial or non-profit)
-
-4. CORE CONTRIBUTOR STATUS MANAGEMENT
-
-a) Core Contributor status may be revoked indefinitely by the remaining Core Contributors if:
-
-- A Core Contributor cannot be reached for a period of one (1) month through reasonable means of communication (including but not limited to email, Discord, GitHub, or other project communication channels)
-- AND the Core Contributor has not contributed to the project during that one-month period. For purposes of this section, "contributed" means at least one of the following activities:
- - Discussing the Software through project communication channels
- - Committing code changes to the project repository
- - Submitting bug fixes or patches
- - Participating in project-related discussions or decision-making
-
-b) Revocation of Core Contributor status requires a unanimous vote by all other Core Contributors (excluding the Core Contributor whose status is being considered for revocation).
-
-c) Upon revocation of Core Contributor status, the individual shall no longer be considered a Core Contributor and shall lose the rights granted under section 2(c) of this Agreement. However, any Contributions made prior to revocation shall remain subject to the terms of section 5 (CONTRIBUTIONS AND RIGHTS ASSIGNMENT).
-
-d) A revoked Core Contributor may be reinstated to Core Contributor status with a unanimous vote by all current Core Contributors. Upon reinstatement, the individual shall regain all rights granted under section 2(c) of this Agreement.
-
-5. CONTRIBUTIONS AND RIGHTS ASSIGNMENT
-
-By submitting, pushing, or contributing any code, documentation, pull requests, issues, or other materials ("Contributions") to the Automaker project, you agree to the following terms without reservation:
-
-a) **Full Ownership Transfer & Rights Grant:** You hereby assign to the Core Contributors all right, title, and interest in and to your Contributions, including all copyrights, patents, and other intellectual property rights. If such assignment is not effective under applicable law, you grant the Core Contributors an unrestricted, perpetual, worldwide, non-exclusive, royalty-free, fully paid-up, irrevocable, sublicensable, and transferable license to use, reproduce, modify, adapt, publish, translate, create derivative works from, distribute, perform, display, and otherwise exploit your Contributions in any manner they see fit, including for any commercial purpose or Monetization.
-
-b) **No Take-Backs:** You understand and agree that this grant of rights is irrevocable ("no take-backs"). You cannot revoke, rescind, or terminate this grant of rights once your Contribution has been submitted.
-
-c) **Waiver of Moral Rights:** You waive any "moral rights" or other rights with respect to attribution of authorship or integrity of materials regarding your Contributions that you may have under any applicable law.
-
-d) **Right to Contribute:** You represent and warrant that you are the original author of the Contributions, or that you have sufficient rights to grant the rights conveyed by this section, and that your Contributions do not infringe upon the rights of any third party.
-
-6. TERMINATION
-
-This license will terminate automatically if Licensee breaches any term of this Agreement. Upon termination, Licensee must immediately cease all use of the Software and destroy all copies in their possession.
-
-7. HIGH RISK DISCLAIMER AND LIMITATION OF LIABILITY
-
-a) **AI RISKS:** THE SOFTWARE UTILIZES ARTIFICIAL INTELLIGENCE TO GENERATE CODE, EXECUTE COMMANDS, AND INTERACT WITH YOUR FILE SYSTEM. YOU ACKNOWLEDGE THAT AI SYSTEMS CAN BE UNPREDICTABLE, MAY GENERATE INCORRECT, INSECURE, OR DESTRUCTIVE CODE, AND MAY TAKE ACTIONS THAT COULD DAMAGE YOUR SYSTEM, FILES, OR HARDWARE.
-
-b) **USE AT YOUR OWN RISK:** YOU AGREE THAT YOUR USE OF THE SOFTWARE IS SOLELY AT YOUR OWN RISK. THE CORE CONTRIBUTORS AND LICENSOR DO NOT GUARANTEE THAT THE SOFTWARE OR ANY CODE GENERATED BY IT WILL BE SAFE, BUG-FREE, OR FUNCTIONAL.
-
-c) **NO WARRANTY:** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT.
-
-d) **LIMITATION OF LIABILITY:** IN NO EVENT SHALL THE CORE CONTRIBUTORS, LICENSORS, OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE, INCLUDING BUT NOT LIMITED TO:
-
-- DAMAGE TO HARDWARE OR COMPUTER SYSTEMS
-- DATA LOSS OR CORRUPTION
-- GENERATION OF BAD, VULNERABLE, OR MALICIOUS CODE
-- FINANCIAL LOSSES
-- BUSINESS INTERRUPTION
-
-8. LICENSE AMENDMENTS
-
-Any amendment, modification, or update to this License Agreement must be agreed upon unanimously by all Core Contributors. No changes to this Agreement shall be effective unless all Core Contributors have provided their written consent or approval through a unanimous vote.
-
-9. CONTACT
-
-For inquiries regarding this license or permissions for Monetization, please contact the Core Contributors through the official project channels:
-
-- Agentic Jumpstart Discord: https://discord.gg/JUDWZDN3VT
-- Website: https://automaker.app
-- Email: automakerapp@gmail.com
-
-Any permission for Monetization requires the unanimous written consent of all Core Contributors.
-
-10. GOVERNING LAW
-
-This Agreement shall be governed by and construed in accordance with the laws of the State of Tennessee, USA, without regard to conflict of law principles.
-
-By using the Software, you acknowledge that you have read this Agreement, understand it, and agree to be bound by its terms and conditions.
+**This project is no longer actively maintained.** The codebase is provided as-is for those who wish to use, study, or fork it. No bug fixes, security updates, or new features are being developed. Community contributions may still be accepted, but there is no guarantee of review or merge.
---
+MIT License
+
Copyright (c) 2025 Automaker Core Contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
index a34269b2..49b14343 100644
--- a/README.md
+++ b/README.md
@@ -14,6 +14,10 @@
**Stop typing code. Start directing AI agents.**
+> **[!WARNING]**
+>
+> **This project is no longer actively maintained.** The codebase is provided as-is. No bug fixes, security updates, or new features are being developed.
+
Table of Contents
@@ -669,26 +673,10 @@ Join the **Agentic Jumpstart** Discord to connect with other builders exploring
👉 [Agentic Jumpstart Discord](https://discord.gg/jjem7aEDKU)
+## Project Status
+
+**This project is no longer actively maintained.** The codebase is provided as-is for those who wish to use, study, or fork it. No bug fixes, security updates, or new features are being developed. Community contributions may still be accepted, but there is no guarantee of review or merge.
+
## License
-This project is licensed under the **Automaker License Agreement**. See [LICENSE](LICENSE) for the full text.
-
-**Summary of Terms:**
-
-- **Allowed:**
- - **Build Anything:** You can clone and use Automaker locally or in your organization to build ANY product (commercial or free).
- - **Internal Use:** You can use it internally within your company (commercial or non-profit) without restriction.
- - **Modify:** You can modify the code for internal use within your organization (commercial or non-profit).
-
-- **Restricted (The "No Monetization of the Tool" Rule):**
- - **No Resale:** You cannot resell Automaker itself.
- - **No SaaS:** You cannot host Automaker as a service for others.
- - **No Monetizing Mods:** You cannot distribute modified versions of Automaker for money.
-
-- **Liability:**
- - **Use at Own Risk:** This tool uses AI. We are **NOT** responsible if it breaks your computer, deletes your files, or generates bad code. You assume all risk.
-
-- **Contributing:**
- - By contributing to this repository, you grant the Core Contributors full, irrevocable rights to your code (copyright assignment).
-
-**Core Contributors** (Cody Seibert (webdevcody), SuperComboGamer (SCG), Kacper Lachowicz (Shironex, Shirone), and Ben Scott (trueheads)) are granted perpetual, royalty-free licenses for any use, including monetization.
+This project is licensed under the **MIT License**. See [LICENSE](LICENSE) for the full text.
diff --git a/package.json b/package.json
index e2340d20..27d5a64b 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,7 @@
{
"name": "automaker",
"version": "0.13.0",
+ "license": "MIT",
"private": true,
"engines": {
"node": ">=22.0.0 <23.0.0"
From c70344156d3216a5ab828cee2b6756d73b39ce95 Mon Sep 17 00:00:00 2001
From: Shirone
Date: Sun, 15 Feb 2026 16:46:29 +0100
Subject: [PATCH 19/21] chore: update .gitignore to include new configuration
files
- Added .mcp.json and .planning to .gitignore to prevent tracking of configuration files.
---
.gitignore | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.gitignore b/.gitignore
index 7d6c7b0e..d7739863 100644
--- a/.gitignore
+++ b/.gitignore
@@ -95,3 +95,5 @@ data/.api-key
data/credentials.json
data/
.codex/
+.mcp.json
+.planning
\ No newline at end of file
From 8ed13564f6524f3658de10e02e568c08814d337f Mon Sep 17 00:00:00 2001
From: Shirone
Date: Sun, 15 Feb 2026 16:59:54 +0100
Subject: [PATCH 20/21] fix: address PR #757 review comments
- Extract getNvmWindowsCliPaths() helper to DRY up NVM_SYMLINK logic
- Update DEFAULT_MODELS.codex to gpt53Codex
- Simplify redundant ternary in thinking-level-selector
- Replace local supportsReasoningEffort with shared import from @automaker/types
- Use model.id fallback in phase-model-selector thinking level resolution
Co-Authored-By: Claude Opus 4.6
---
.../shared/thinking-level-selector.tsx | 2 +-
.../model-defaults/phase-model-selector.tsx | 4 +-
.../providers/codex-model-configuration.tsx | 13 +------
libs/platform/src/system-paths.ts | 37 ++++++++-----------
libs/types/src/model.ts | 2 +-
5 files changed, 21 insertions(+), 37 deletions(-)
diff --git a/apps/ui/src/components/views/board-view/shared/thinking-level-selector.tsx b/apps/ui/src/components/views/board-view/shared/thinking-level-selector.tsx
index c74b3e9a..5164e4fa 100644
--- a/apps/ui/src/components/views/board-view/shared/thinking-level-selector.tsx
+++ b/apps/ui/src/components/views/board-view/shared/thinking-level-selector.tsx
@@ -19,7 +19,7 @@ export function ThinkingLevelSelector({
testIdPrefix = 'thinking-level',
model,
}: ThinkingLevelSelectorProps) {
- const levels = model ? getThinkingLevelsForModel(model) : getThinkingLevelsForModel('');
+ const levels = getThinkingLevelsForModel(model || '');
return (
diff --git a/apps/ui/src/components/views/settings-view/model-defaults/phase-model-selector.tsx b/apps/ui/src/components/views/settings-view/model-defaults/phase-model-selector.tsx
index 25424fa6..0f3c7889 100644
--- a/apps/ui/src/components/views/settings-view/model-defaults/phase-model-selector.tsx
+++ b/apps/ui/src/components/views/settings-view/model-defaults/phase-model-selector.tsx
@@ -1297,7 +1297,7 @@ export function PhaseModelSelector({
Thinking Level