Merge branch 'v0.9.0rc' into remove-sandbox-as-it-is-broken

This commit is contained in:
webdevcody
2026-01-07 15:01:31 -05:00
115 changed files with 8734 additions and 401 deletions

View File

@@ -9,8 +9,11 @@ import type {
FeatureTextFilePath,
ModelAlias,
PlanningMode,
ThinkingLevel,
ModelProvider,
AIProfile,
CursorModelId,
CodexModelId,
PhaseModelConfig,
PhaseModelKey,
PhaseModelEntry,
@@ -20,12 +23,20 @@ import type {
PipelineStep,
PromptCustomization,
} from '@automaker/types';
import { getAllCursorModelIds, DEFAULT_PHASE_MODELS } from '@automaker/types';
import { getAllCursorModelIds, getAllCodexModelIds, DEFAULT_PHASE_MODELS } from '@automaker/types';
const logger = createLogger('AppStore');
// Re-export types for convenience
export type { ModelAlias };
export type {
ModelAlias,
PlanningMode,
ThinkingLevel,
ModelProvider,
AIProfile,
FeatureTextFilePath,
FeatureImagePath,
};
export type ViewMode =
| 'welcome'
@@ -533,6 +544,15 @@ export interface AppState {
enabledCursorModels: CursorModelId[]; // Which Cursor models are available in feature modal
cursorDefaultModel: CursorModelId; // Default Cursor model selection
// Codex CLI Settings (global)
enabledCodexModels: CodexModelId[]; // Which Codex models are available in feature modal
codexDefaultModel: CodexModelId; // Default Codex model selection
codexAutoLoadAgents: boolean; // Auto-load .codex/AGENTS.md files
codexSandboxMode: 'read-only' | 'workspace-write' | 'danger-full-access'; // Sandbox policy
codexApprovalPolicy: 'untrusted' | 'on-failure' | 'on-request' | 'never'; // Approval policy
codexEnableWebSearch: boolean; // Enable web search capability
codexEnableImages: boolean; // Enable image processing
// Claude Agent SDK Settings
autoLoadClaudeMd: boolean; // Auto-load CLAUDE.md files using SDK's settingSources option
skipSandboxWarning: boolean; // Skip the sandbox environment warning dialog on startup
@@ -595,6 +615,10 @@ export interface AppState {
claudeUsage: ClaudeUsage | null;
claudeUsageLastUpdated: number | null;
// Codex Usage Tracking
codexUsage: CodexUsage | null;
codexUsageLastUpdated: number | null;
// Pipeline Configuration (per-project, keyed by project path)
pipelineConfigByProject: Record<string, PipelineConfig>;
@@ -636,6 +660,41 @@ export type ClaudeUsage = {
// Response type for Claude usage API (can be success or error)
export type ClaudeUsageResponse = ClaudeUsage | { error: string; message?: string };
// Codex Usage types
export type CodexPlanType =
| 'free'
| 'plus'
| 'pro'
| 'team'
| 'business'
| 'enterprise'
| 'edu'
| 'unknown';
export interface CodexCreditsSnapshot {
balance?: string;
unlimited?: boolean;
hasCredits?: boolean;
}
export interface CodexRateLimitWindow {
limit: number;
used: number;
remaining: number;
window: number; // Duration in minutes
resetsAt: number; // Unix timestamp in seconds
}
export interface CodexUsage {
planType: CodexPlanType | null;
credits: CodexCreditsSnapshot | null;
rateLimits: {
session?: CodexRateLimitWindow;
weekly?: CodexRateLimitWindow;
} | null;
lastUpdated: string;
}
/**
* Check if Claude usage is at its limit (any of: session >= 100%, weekly >= 100%, OR cost >= limit)
* Returns true if any limit is reached, meaning auto mode should pause feature pickup.
@@ -839,6 +898,20 @@ export interface AppActions {
setCursorDefaultModel: (model: CursorModelId) => void;
toggleCursorModel: (model: CursorModelId, enabled: boolean) => void;
// Codex CLI Settings actions
setEnabledCodexModels: (models: CodexModelId[]) => void;
setCodexDefaultModel: (model: CodexModelId) => void;
toggleCodexModel: (model: CodexModelId, enabled: boolean) => void;
setCodexAutoLoadAgents: (enabled: boolean) => Promise<void>;
setCodexSandboxMode: (
mode: 'read-only' | 'workspace-write' | 'danger-full-access'
) => Promise<void>;
setCodexApprovalPolicy: (
policy: 'untrusted' | 'on-failure' | 'on-request' | 'never'
) => Promise<void>;
setCodexEnableWebSearch: (enabled: boolean) => Promise<void>;
setCodexEnableImages: (enabled: boolean) => Promise<void>;
// Claude Agent SDK Settings actions
setAutoLoadClaudeMd: (enabled: boolean) => Promise<void>;
setSkipSandboxWarning: (skip: boolean) => Promise<void>;
@@ -970,6 +1043,14 @@ export interface AppActions {
setRecentFolders: (folders: string[]) => void;
addRecentFolder: (folder: string) => void;
// Claude Usage Tracking actions
setClaudeRefreshInterval: (interval: number) => void;
setClaudeUsageLastUpdated: (timestamp: number) => void;
setClaudeUsage: (usage: ClaudeUsage | null) => void;
// Codex Usage Tracking actions
setCodexUsage: (usage: CodexUsage | null) => void;
// Reset
reset: () => void;
}
@@ -1061,6 +1142,13 @@ const initialState: AppState = {
favoriteModels: [],
enabledCursorModels: getAllCursorModelIds(), // All Cursor models enabled by default
cursorDefaultModel: 'auto', // Default to auto selection
enabledCodexModels: getAllCodexModelIds(), // All Codex models enabled by default
codexDefaultModel: 'gpt-5.2-codex', // Default to GPT-5.2-Codex
codexAutoLoadAgents: false, // Default to disabled (user must opt-in)
codexSandboxMode: 'workspace-write', // Default to workspace-write for safety
codexApprovalPolicy: 'on-request', // Default to on-request for balanced safety
codexEnableWebSearch: false, // Default to disabled
codexEnableImages: false, // Default to disabled
autoLoadClaudeMd: false, // Default to disabled (user must opt-in)
skipSandboxWarning: false, // Default to disabled (show sandbox warning dialog)
mcpServers: [], // No MCP servers configured by default
@@ -1095,6 +1183,8 @@ const initialState: AppState = {
claudeRefreshInterval: 60,
claudeUsage: null,
claudeUsageLastUpdated: null,
codexUsage: null,
codexUsageLastUpdated: null,
pipelineConfigByProject: {},
// UI State (previously in localStorage, now synced via API)
worktreePanelCollapsed: false,
@@ -1753,6 +1843,41 @@ export const useAppStore = create<AppState & AppActions>()((set, get) => ({
: state.enabledCursorModels.filter((m) => m !== model),
})),
// Codex CLI Settings actions
setEnabledCodexModels: (models) => set({ enabledCodexModels: models }),
setCodexDefaultModel: (model) => set({ codexDefaultModel: model }),
toggleCodexModel: (model, enabled) =>
set((state) => ({
enabledCodexModels: enabled
? [...state.enabledCodexModels, model]
: state.enabledCodexModels.filter((m) => m !== model),
})),
setCodexAutoLoadAgents: async (enabled) => {
set({ codexAutoLoadAgents: enabled });
const { syncSettingsToServer } = await import('@/hooks/use-settings-migration');
await syncSettingsToServer();
},
setCodexSandboxMode: async (mode) => {
set({ codexSandboxMode: mode });
const { syncSettingsToServer } = await import('@/hooks/use-settings-migration');
await syncSettingsToServer();
},
setCodexApprovalPolicy: async (policy) => {
set({ codexApprovalPolicy: policy });
const { syncSettingsToServer } = await import('@/hooks/use-settings-migration');
await syncSettingsToServer();
},
setCodexEnableWebSearch: async (enabled) => {
set({ codexEnableWebSearch: enabled });
const { syncSettingsToServer } = await import('@/hooks/use-settings-migration');
await syncSettingsToServer();
},
setCodexEnableImages: async (enabled) => {
set({ codexEnableImages: enabled });
const { syncSettingsToServer } = await import('@/hooks/use-settings-migration');
await syncSettingsToServer();
},
// Claude Agent SDK Settings actions
setAutoLoadClaudeMd: async (enabled) => {
const previous = get().autoLoadClaudeMd;
@@ -2826,6 +2951,13 @@ export const useAppStore = create<AppState & AppActions>()((set, get) => ({
claudeUsageLastUpdated: usage ? Date.now() : null,
}),
// Codex Usage Tracking actions
setCodexUsage: (usage: CodexUsage | null) =>
set({
codexUsage: usage,
codexUsageLastUpdated: usage ? Date.now() : null,
}),
// Pipeline actions
setPipelineConfig: (projectPath, config) => {
set({