diff --git a/apps/backend/agents/auto_claude_tools.py b/apps/backend/agents/auto_claude_tools.py deleted file mode 100644 index ad6dc0a5..00000000 --- a/apps/backend/agents/auto_claude_tools.py +++ /dev/null @@ -1,62 +0,0 @@ -""" -Custom MCP Tools for Auto-Claude Agents -======================================== - -DEPRECATED: This module is now a compatibility shim. -Please import from the tools_pkg package instead: - - from agents.tools_pkg import create_auto_claude_mcp_server, get_allowed_tools - -This file remains for backward compatibility with existing imports. -All functionality has been moved to the tools_pkg package for better -organization and maintainability. -""" - -# Import everything from the package to maintain backward compatibility -# Use try/except to handle both relative and absolute imports -try: - from .tools_pkg import ( - ELECTRON_TOOLS, - TOOL_GET_BUILD_PROGRESS, - TOOL_GET_SESSION_CONTEXT, - TOOL_RECORD_DISCOVERY, - TOOL_RECORD_GOTCHA, - TOOL_UPDATE_QA_STATUS, - TOOL_UPDATE_SUBTASK_STATUS, - create_auto_claude_mcp_server, - get_allowed_tools, - is_electron_mcp_enabled, - is_tools_available, - ) -except ImportError: - # Fallback for direct execution - import from tools_pkg directly - from tools_pkg import ( - ELECTRON_TOOLS, - TOOL_GET_BUILD_PROGRESS, - TOOL_GET_SESSION_CONTEXT, - TOOL_RECORD_DISCOVERY, - TOOL_RECORD_GOTCHA, - TOOL_UPDATE_QA_STATUS, - TOOL_UPDATE_SUBTASK_STATUS, - create_auto_claude_mcp_server, - get_allowed_tools, - is_electron_mcp_enabled, - is_tools_available, - ) - -__all__ = [ - # Main API - "create_auto_claude_mcp_server", - "get_allowed_tools", - "is_tools_available", - # Tool name constants - "TOOL_UPDATE_SUBTASK_STATUS", - "TOOL_GET_BUILD_PROGRESS", - "TOOL_RECORD_DISCOVERY", - "TOOL_RECORD_GOTCHA", - "TOOL_GET_SESSION_CONTEXT", - "TOOL_UPDATE_QA_STATUS", - # Electron MCP - "ELECTRON_TOOLS", - "is_electron_mcp_enabled", -] diff --git a/apps/backend/cli/main.py b/apps/backend/cli/main.py index 868bdacb..e0f8f29d 100644 --- a/apps/backend/cli/main.py +++ b/apps/backend/cli/main.py @@ -15,10 +15,6 @@ _PARENT_DIR = Path(__file__).parent.parent if str(_PARENT_DIR) not in sys.path: sys.path.insert(0, str(_PARENT_DIR)) -from ui import ( - Icons, - icon, -) from .batch_commands import ( handle_batch_cleanup_command, @@ -201,13 +197,6 @@ Environment Variables: help="Show human review/approval status for a spec", ) - # Dev mode (deprecated) - parser.add_argument( - "--dev", - action="store_true", - help="[Deprecated] No longer has any effect - kept for compatibility", - ) - # Non-interactive mode (for UI/automation) parser.add_argument( "--auto-continue", @@ -290,16 +279,10 @@ def main() -> None: # Get model (with env var fallback) model = args.model or os.environ.get("AUTO_BUILD_MODEL", DEFAULT_MODEL) - # Note: --dev flag is deprecated but kept for API compatibility - if args.dev: - print( - f"\n{icon(Icons.GEAR)} Note: --dev flag is deprecated. All specs now use .auto-claude/specs/\n" - ) - # Handle --list command if args.list: print_banner() - print_specs_list(project_dir, args.dev) + print_specs_list(project_dir) return # Handle --list-worktrees command @@ -337,14 +320,14 @@ def main() -> None: sys.exit(1) # Find the spec - debug("run.py", "Finding spec", spec_identifier=args.spec, dev_mode=args.dev) - spec_dir = find_spec(project_dir, args.spec, args.dev) + debug("run.py", "Finding spec", spec_identifier=args.spec) + spec_dir = find_spec(project_dir, args.spec) if not spec_dir: debug_error("run.py", "Spec not found", spec=args.spec) print_banner() print(f"\nError: Spec '{args.spec}' not found") print("\nAvailable specs:") - print_specs_list(project_dir, args.dev) + print_specs_list(project_dir) sys.exit(1) debug_success("run.py", "Spec found", spec_dir=str(spec_dir)) diff --git a/apps/backend/cli/spec_commands.py b/apps/backend/cli/spec_commands.py index 2fa1d02c..ed2b5a38 100644 --- a/apps/backend/cli/spec_commands.py +++ b/apps/backend/cli/spec_commands.py @@ -19,18 +19,17 @@ from workspace import get_existing_build_worktree from .utils import get_specs_dir -def list_specs(project_dir: Path, dev_mode: bool = False) -> list[dict]: +def list_specs(project_dir: Path) -> list[dict]: """ List all specs in the project. Args: project_dir: Project root directory - dev_mode: If True, use dev/auto-claude/specs/ Returns: List of spec info dicts with keys: number, name, path, status, progress """ - specs_dir = get_specs_dir(project_dir, dev_mode) + specs_dir = get_specs_dir(project_dir) specs = [] if not specs_dir.exists(): @@ -93,19 +92,16 @@ def list_specs(project_dir: Path, dev_mode: bool = False) -> list[dict]: return specs -def print_specs_list( - project_dir: Path, dev_mode: bool = False, auto_create: bool = True -) -> None: +def print_specs_list(project_dir: Path, auto_create: bool = True) -> None: """Print a formatted list of all specs. Args: project_dir: Project root directory - dev_mode: If True, use dev/auto-claude/specs/ auto_create: If True and no specs exist, automatically launch spec creation """ import subprocess - specs = list_specs(project_dir, dev_mode) + specs = list_specs(project_dir) if not specs: print("\nNo specs found.") diff --git a/apps/backend/cli/utils.py b/apps/backend/cli/utils.py index c5dd6766..f1895465 100644 --- a/apps/backend/cli/utils.py +++ b/apps/backend/cli/utils.py @@ -54,21 +54,18 @@ def setup_environment() -> Path: return script_dir -def find_spec( - project_dir: Path, spec_identifier: str, dev_mode: bool = False -) -> Path | None: +def find_spec(project_dir: Path, spec_identifier: str) -> Path | None: """ Find a spec by number or full name. Args: project_dir: Project root directory spec_identifier: Either "001" or "001-feature-name" - dev_mode: If True, use dev/auto-claude/specs/ Returns: Path to spec folder, or None if not found """ - specs_dir = get_specs_dir(project_dir, dev_mode) + specs_dir = get_specs_dir(project_dir) if specs_dir.exists(): # Try exact match first diff --git a/apps/backend/implementation_plan/main.py b/apps/backend/implementation_plan/main.py deleted file mode 100644 index 733e78a4..00000000 --- a/apps/backend/implementation_plan/main.py +++ /dev/null @@ -1,168 +0,0 @@ -#!/usr/bin/env python3 -""" -Implementation Plan Manager -============================ - -DEPRECATED: This module is now a compatibility shim. The implementation has been -refactored into the implementation_plan/ package for better modularity. - -Please import from the package directly: - from implementation_plan import ImplementationPlan, Subtask, Phase, etc. - -This file re-exports all public APIs for backwards compatibility. - -Core data structures and utilities for subtask-based implementation plans. -Replaces the test-centric feature_list.json with implementation_plan.json. - -The key insight: Tests verify outcomes, but SUBTASKS define implementation steps. -For complex multi-service features, implementation order matters. - -Workflow Types: -- feature: Standard multi-service feature (phases = services) -- refactor: Migration/refactor work (phases = stages: add, migrate, remove) -- investigation: Bug hunting (phases = investigate, hypothesize, fix) -- migration: Data migration (phases = prepare, test, execute, cleanup) -- simple: Single-service enhancement (minimal overhead) -""" - -# Re-export everything from the implementation_plan package -from implementation_plan import ( - Chunk, - ChunkStatus, - ImplementationPlan, - Phase, - PhaseType, - Subtask, - SubtaskStatus, - Verification, - VerificationType, - WorkflowType, - create_feature_plan, - create_investigation_plan, - create_refactor_plan, -) - -__all__ = [ - # Enums - "WorkflowType", - "PhaseType", - "SubtaskStatus", - "VerificationType", - # Models - "Verification", - "Subtask", - "Phase", - "ImplementationPlan", - # Factories - "create_feature_plan", - "create_investigation_plan", - "create_refactor_plan", - # Backwards compatibility - "Chunk", - "ChunkStatus", -] - - -# CLI for testing -if __name__ == "__main__": - import json - import sys - from pathlib import Path - - if len(sys.argv) < 2: - print("Usage: python implementation_plan.py ") - print(" python implementation_plan.py --demo") - sys.exit(1) - - if sys.argv[1] == "--demo": - # Create a demo plan - plan = create_feature_plan( - feature="Avatar Upload with Processing", - services=["backend", "worker", "frontend"], - phases_config=[ - { - "name": "Backend Foundation", - "parallel_safe": True, - "subtasks": [ - { - "id": "avatar-model", - "service": "backend", - "description": "Add avatar fields to User model", - "files_to_modify": ["app/models/user.py"], - "files_to_create": ["migrations/add_avatar.py"], - "verification": { - "type": "command", - "run": "flask db upgrade", - }, - }, - { - "id": "avatar-endpoint", - "service": "backend", - "description": "POST /api/users/avatar endpoint", - "files_to_modify": ["app/routes/users.py"], - "patterns_from": ["app/routes/profile.py"], - "verification": { - "type": "api", - "method": "POST", - "url": "/api/users/avatar", - }, - }, - ], - }, - { - "name": "Worker Pipeline", - "depends_on": [1], - "subtasks": [ - { - "id": "image-task", - "service": "worker", - "description": "Celery task for image processing", - "files_to_create": ["app/tasks/images.py"], - "patterns_from": ["app/tasks/reports.py"], - }, - ], - }, - { - "name": "Frontend", - "depends_on": [1], - "subtasks": [ - { - "id": "avatar-component", - "service": "frontend", - "description": "AvatarUpload React component", - "files_to_create": ["src/components/AvatarUpload.tsx"], - "patterns_from": ["src/components/FileUpload.tsx"], - }, - ], - }, - { - "name": "Integration", - "depends_on": [2, 3], - "type": "integration", - "subtasks": [ - { - "id": "e2e-wiring", - "all_services": True, - "description": "Connect frontend → backend → worker", - "verification": { - "type": "browser", - "scenario": "Upload → Process → Display", - }, - }, - ], - }, - ], - ) - plan.final_acceptance = [ - "User can upload avatar from profile page", - "Avatar is automatically resized", - "Large/invalid files show error", - ] - - print(json.dumps(plan.to_dict(), indent=2)) - print("\n---\n") - print(plan.get_status_summary()) - else: - # Load and display existing plan - plan = ImplementationPlan.load(Path(sys.argv[1])) - print(plan.get_status_summary()) diff --git a/apps/backend/runners/github/batch_issues.py b/apps/backend/runners/github/batch_issues.py index 765c689e..743a172e 100644 --- a/apps/backend/runners/github/batch_issues.py +++ b/apps/backend/runners/github/batch_issues.py @@ -240,30 +240,6 @@ Respond with JSON only: return response_text -# Keep old class for backwards compatibility but mark as deprecated -class ClaudeSimilarityDetector(ClaudeBatchAnalyzer): - """DEPRECATED: Use ClaudeBatchAnalyzer instead.""" - - async def compare_issues( - self, - repo: str, - issue_a: dict[str, Any], - issue_b: dict[str, Any], - ) -> dict[str, Any]: - """DEPRECATED: Pairwise comparison. Use analyze_and_batch_issues instead.""" - logger.warning("ClaudeSimilarityDetector.compare_issues is deprecated") - # Simple fallback for any code still using this - return { - "is_similar": False, - "overall_score": 0.0, - "reasoning": "DEPRECATED: Use ClaudeBatchAnalyzer.analyze_and_batch_issues", - } - - async def precompute_embeddings(self, repo: str, issues: list[dict]) -> int: - """No-op for compatibility.""" - return 0 - - class BatchStatus(str, Enum): """Status of an issue batch.""" @@ -446,12 +422,9 @@ class IssueBatcher: self.max_batch_size = max_batch_size self.validate_batches_enabled = validate_batches - # Initialize Claude batch analyzer (replaces pairwise similarity detector) + # Initialize Claude batch analyzer self.analyzer = ClaudeBatchAnalyzer(project_dir=self.project_dir) - # Keep detector for backwards compatibility (deprecated) - self.detector = self.analyzer - # Initialize batch validator (uses Claude SDK with OAuth token) self.validator = ( BatchValidator( diff --git a/apps/backend/runners/spec_runner.py b/apps/backend/runners/spec_runner.py index 660ab6d2..fe48bf8a 100644 --- a/apps/backend/runners/spec_runner.py +++ b/apps/backend/runners/spec_runner.py @@ -95,7 +95,7 @@ from debug import debug, debug_error, debug_section, debug_success from phase_config import resolve_model_id from review import ReviewState from spec import SpecOrchestrator -from ui import Icons, highlight, icon, muted, print_section, print_status +from ui import Icons, highlight, muted, print_section, print_status def main(): @@ -177,11 +177,6 @@ Examples: action="store_true", help="Use heuristic complexity assessment instead of AI (faster but less accurate)", ) - parser.add_argument( - "--dev", - action="store_true", - help="[Deprecated] No longer has any effect - kept for compatibility", - ) parser.add_argument( "--no-build", action="store_true", @@ -236,12 +231,6 @@ Examples: project_dir = parent break - # Note: --dev flag is deprecated but kept for API compatibility - if args.dev: - print( - f"\n{icon(Icons.GEAR)} Note: --dev flag is deprecated. All specs now go to .auto-claude/specs/\n" - ) - # Resolve model shorthand to full model ID resolved_model = resolve_model_id(args.model) @@ -267,7 +256,6 @@ Examples: thinking_level=args.thinking_level, complexity_override=args.complexity, use_ai_assessment=not args.no_ai_assessment, - dev_mode=args.dev, ) try: @@ -330,10 +318,6 @@ Examples: "--auto-continue", # Non-interactive mode for chained execution ] - # Pass through dev mode - if args.dev: - run_cmd.append("--dev") - # Note: Model configuration for subsequent phases (planning, coding, qa) # is read from task_metadata.json by run.py, so we don't pass it here. # This allows per-phase configuration when using Auto profile. diff --git a/apps/backend/spec/complexity.py b/apps/backend/spec/complexity.py index cf38c47d..5be32544 100644 --- a/apps/backend/spec/complexity.py +++ b/apps/backend/spec/complexity.py @@ -435,9 +435,7 @@ async def run_ai_complexity_assessment( return None -def save_assessment( - spec_dir: Path, assessment: ComplexityAssessment, dev_mode: bool = False -) -> Path: +def save_assessment(spec_dir: Path, assessment: ComplexityAssessment) -> Path: """Save complexity assessment to file.""" assessment_file = spec_dir / "complexity_assessment.json" phases = assessment.phases_to_run() @@ -456,7 +454,6 @@ def save_assessment( "phases_to_run": phases, "needs_research": assessment.needs_research, "needs_self_critique": assessment.needs_self_critique, - "dev_mode": dev_mode, "created_at": datetime.now().isoformat(), }, f, diff --git a/apps/backend/spec/pipeline/models.py b/apps/backend/spec/pipeline/models.py index f1a08303..6675c9c6 100644 --- a/apps/backend/spec/pipeline/models.py +++ b/apps/backend/spec/pipeline/models.py @@ -21,7 +21,7 @@ if TYPE_CHECKING: from core.workspace.models import SpecNumberLock -def get_specs_dir(project_dir: Path, dev_mode: bool = False) -> Path: +def get_specs_dir(project_dir: Path) -> Path: """Get the specs directory path. IMPORTANT: Only .auto-claude/ is considered an "installed" auto-claude. @@ -32,7 +32,6 @@ def get_specs_dir(project_dir: Path, dev_mode: bool = False) -> Path: Args: project_dir: The project root directory - dev_mode: Deprecated, kept for API compatibility. Has no effect. Returns: Path to the specs directory within .auto-claude/ diff --git a/apps/backend/spec/pipeline/orchestrator.py b/apps/backend/spec/pipeline/orchestrator.py index 1f57cd16..76c04d47 100644 --- a/apps/backend/spec/pipeline/orchestrator.py +++ b/apps/backend/spec/pipeline/orchestrator.py @@ -61,7 +61,6 @@ class SpecOrchestrator: thinking_level: str = "medium", # Thinking level for extended thinking complexity_override: str | None = None, # Force a specific complexity use_ai_assessment: bool = True, # Use AI for complexity assessment (vs heuristics) - dev_mode: bool = False, # Dev mode: specs in gitignored folder, code changes to auto-claude/ ): """Initialize the spec orchestrator. @@ -74,7 +73,6 @@ class SpecOrchestrator: thinking_level: Thinking level (none, low, medium, high, ultrathink) complexity_override: Force a specific complexity level use_ai_assessment: Whether to use AI for complexity assessment - dev_mode: Deprecated, kept for API compatibility """ self.project_dir = Path(project_dir) self.task_description = task_description @@ -82,10 +80,9 @@ class SpecOrchestrator: self.thinking_level = thinking_level self.complexity_override = complexity_override self.use_ai_assessment = use_ai_assessment - self.dev_mode = dev_mode # Get the appropriate specs directory (within the project) - self.specs_dir = get_specs_dir(self.project_dir, dev_mode) + self.specs_dir = get_specs_dir(self.project_dir) # Clean up orphaned pending folders before creating new spec cleanup_orphaned_pending_folders(self.specs_dir) @@ -462,7 +459,7 @@ class SpecOrchestrator: # Save assessment if not assessment_file.exists(): - complexity.save_assessment(self.spec_dir, self.assessment, self.dev_mode) + complexity.save_assessment(self.spec_dir, self.assessment) return phases.PhaseResult( "complexity_assessment", True, [str(assessment_file)], [], 0 diff --git a/apps/frontend/src/main/ipc-handlers/project-handlers.ts b/apps/frontend/src/main/ipc-handlers/project-handlers.ts index c0c65a20..ea139151 100644 --- a/apps/frontend/src/main/ipc-handlers/project-handlers.ts +++ b/apps/frontend/src/main/ipc-handlers/project-handlers.ts @@ -319,29 +319,6 @@ export function registerProjectHandlers( } ); - // PROJECT_UPDATE_AUTOBUILD is deprecated - .auto-claude only contains data, no code to update - // Kept for API compatibility, returns success immediately - ipcMain.handle( - IPC_CHANNELS.PROJECT_UPDATE_AUTOBUILD, - async (_, projectId: string): Promise> => { - try { - const project = projectStore.getProject(projectId); - if (!project) { - return { success: false, error: 'Project not found' }; - } - - // Nothing to update - .auto-claude only contains data directories - // The framework runs from the source repo - return { success: true, data: { success: true } }; - } catch (error) { - return { - success: false, - error: error instanceof Error ? error.message : 'Unknown error' - }; - } - } - ); - // PROJECT_CHECK_VERSION now just checks if project is initialized // Version tracking for .auto-claude is removed since it only contains data ipcMain.handle( diff --git a/apps/frontend/src/preload/api/project-api.ts b/apps/frontend/src/preload/api/project-api.ts index 420f8270..3ad83a00 100644 --- a/apps/frontend/src/preload/api/project-api.ts +++ b/apps/frontend/src/preload/api/project-api.ts @@ -31,7 +31,6 @@ export interface ProjectAPI { settings: Partial ) => Promise; initializeProject: (projectId: string) => Promise>; - updateProjectAutoBuild: (projectId: string) => Promise>; checkProjectVersion: (projectId: string) => Promise>; // Tab State (persisted in main process for reliability) @@ -155,9 +154,6 @@ export const createProjectAPI = (): ProjectAPI => ({ initializeProject: (projectId: string): Promise> => ipcRenderer.invoke(IPC_CHANNELS.PROJECT_INITIALIZE, projectId), - updateProjectAutoBuild: (projectId: string): Promise> => - ipcRenderer.invoke(IPC_CHANNELS.PROJECT_UPDATE_AUTOBUILD, projectId), - checkProjectVersion: (projectId: string): Promise> => ipcRenderer.invoke(IPC_CHANNELS.PROJECT_CHECK_VERSION, projectId), diff --git a/apps/frontend/src/renderer/components/Sidebar.tsx b/apps/frontend/src/renderer/components/Sidebar.tsx index e093fb56..d6be635a 100644 --- a/apps/frontend/src/renderer/components/Sidebar.tsx +++ b/apps/frontend/src/renderer/components/Sidebar.tsx @@ -40,9 +40,7 @@ import { cn } from '../lib/utils'; import { useProjectStore, removeProject, - initializeProject, - checkProjectVersion, - updateProjectAutoBuild + initializeProject } from '../stores/project-store'; import { useSettingsStore } from '../stores/settings-store'; import { AddProjectModal } from './AddProjectModal'; @@ -96,11 +94,9 @@ export function Sidebar({ const [showAddProjectModal, setShowAddProjectModal] = useState(false); const [showInitDialog, setShowInitDialog] = useState(false); - const [showUpdateDialog, setShowUpdateDialog] = useState(false); const [showGitSetupModal, setShowGitSetupModal] = useState(false); const [gitStatus, setGitStatus] = useState(null); const [pendingProject, setPendingProject] = useState(null); - const [_versionInfo, setVersionInfo] = useState(null); const [isInitializing, setIsInitializing] = useState(false); const selectedProject = projects.find((p) => p.id === selectedProjectId); @@ -140,20 +136,6 @@ export function Sidebar({ return () => window.removeEventListener('keydown', handleKeyDown); }, [selectedProjectId, onViewChange]); - // Check for updates when project changes - useEffect(() => { - const checkUpdates = async () => { - if (selectedProjectId && settings.autoUpdateAutoBuild) { - const info = await checkProjectVersion(selectedProjectId); - if (info?.updateAvailable) { - setVersionInfo(info); - setShowUpdateDialog(true); - } - } - }; - checkUpdates(); - }, [selectedProjectId, settings.autoUpdateAutoBuild]); - // Check git status when project changes useEffect(() => { const checkGit = async () => { @@ -211,26 +193,6 @@ export function Sidebar({ setPendingProject(null); }; - const _handleUpdate = async () => { - if (!selectedProjectId) return; - - setIsInitializing(true); - try { - const result = await updateProjectAutoBuild(selectedProjectId); - if (result?.success) { - setShowUpdateDialog(false); - setVersionInfo(null); - } - } finally { - setIsInitializing(false); - } - }; - - const _handleSkipUpdate = () => { - setShowUpdateDialog(false); - setVersionInfo(null); - }; - const handleGitInitialized = async () => { // Refresh git status after initialization if (selectedProject) { @@ -439,26 +401,6 @@ export function Sidebar({ - {/* Update Auto Claude Dialog - Deprecated, updateAvailable is always false now */} - - - - - - {t('dialogs:update.title')} - - - {t('dialogs:update.projectInitialized')} - - - - - - - - {/* Add Project Modal */} Promise; - handleUpdate: () => Promise; } export function GeneralSettings({ @@ -41,8 +40,7 @@ export function GeneralSettings({ versionInfo, isCheckingVersion, isUpdating, - handleInitialize, - handleUpdate: _handleUpdate + handleInitialize }: GeneralSettingsProps) { return ( <> diff --git a/apps/frontend/src/renderer/components/project-settings/hooks/useProjectSettings.ts b/apps/frontend/src/renderer/components/project-settings/hooks/useProjectSettings.ts index 4cb47530..448eded7 100644 --- a/apps/frontend/src/renderer/components/project-settings/hooks/useProjectSettings.ts +++ b/apps/frontend/src/renderer/components/project-settings/hooks/useProjectSettings.ts @@ -2,8 +2,7 @@ import { useState, useEffect } from 'react'; import { updateProjectSettings, checkProjectVersion, - initializeProject, - updateProjectAutoBuild + initializeProject } from '../../../stores/project-store'; import { checkGitHubConnection as checkGitHubConnectionGlobal } from '../../../stores/github'; import type { @@ -68,7 +67,6 @@ export interface UseProjectSettingsReturn { // Actions handleInitialize: () => Promise; - handleUpdate: () => Promise; handleSaveEnv: () => Promise; handleClaudeSetup: () => Promise; handleSave: (onClose: () => void) => Promise; @@ -262,24 +260,6 @@ export function useProjectSettings( } }; - const handleUpdate = async () => { - setIsUpdating(true); - setError(null); - try { - const result = await updateProjectAutoBuild(project.id); - if (result?.success) { - const info = await checkProjectVersion(project.id); - setVersionInfo(info); - } else { - setError(result?.error || 'Failed to update'); - } - } catch (err) { - setError(err instanceof Error ? err.message : 'Unknown error'); - } finally { - setIsUpdating(false); - } - }; - const handleSaveEnv = async () => { if (!envConfig) return; @@ -397,7 +377,6 @@ export function useProjectSettings( linearConnectionStatus, isCheckingLinear, handleInitialize, - handleUpdate, handleSaveEnv, handleClaudeSetup, handleSave diff --git a/apps/frontend/src/renderer/components/settings/ProjectSettingsContent.tsx b/apps/frontend/src/renderer/components/settings/ProjectSettingsContent.tsx index d6c0d56c..8500da76 100644 --- a/apps/frontend/src/renderer/components/settings/ProjectSettingsContent.tsx +++ b/apps/frontend/src/renderer/components/settings/ProjectSettingsContent.tsx @@ -100,7 +100,6 @@ function ProjectSettingsContentInner({ linearConnectionStatus, isCheckingLinear, handleInitialize, - handleUpdate, handleClaudeSetup, error } = hook; @@ -146,7 +145,6 @@ function ProjectSettingsContentInner({ linearConnectionStatus={linearConnectionStatus} isCheckingLinear={isCheckingLinear} handleInitialize={handleInitialize} - handleUpdate={handleUpdate} handleClaudeSetup={handleClaudeSetup} onOpenLinearImport={() => setShowLinearImportModal(true)} /> diff --git a/apps/frontend/src/renderer/components/settings/sections/SectionRouter.tsx b/apps/frontend/src/renderer/components/settings/sections/SectionRouter.tsx index 73894391..710de08f 100644 --- a/apps/frontend/src/renderer/components/settings/sections/SectionRouter.tsx +++ b/apps/frontend/src/renderer/components/settings/sections/SectionRouter.tsx @@ -35,7 +35,6 @@ interface SectionRouterProps { linearConnectionStatus: LinearSyncStatus | null; isCheckingLinear: boolean; handleInitialize: () => Promise; - handleUpdate: () => Promise; handleClaudeSetup: () => Promise; onOpenLinearImport: () => void; } @@ -71,7 +70,6 @@ export function SectionRouter({ linearConnectionStatus, isCheckingLinear, handleInitialize, - handleUpdate, handleClaudeSetup, onOpenLinearImport }: SectionRouterProps) { @@ -90,7 +88,6 @@ export function SectionRouter({ isCheckingVersion={isCheckingVersion} isUpdating={isUpdating} handleInitialize={handleInitialize} - handleUpdate={handleUpdate} /> ); diff --git a/apps/frontend/src/renderer/components/settings/utils/hookProxyFactory.ts b/apps/frontend/src/renderer/components/settings/utils/hookProxyFactory.ts index dcc071b6..0f7ae8bb 100644 --- a/apps/frontend/src/renderer/components/settings/utils/hookProxyFactory.ts +++ b/apps/frontend/src/renderer/components/settings/utils/hookProxyFactory.ts @@ -47,7 +47,6 @@ export function createHookProxy( get linearConnectionStatus() { return hookRef.current.linearConnectionStatus; }, get isCheckingLinear() { return hookRef.current.isCheckingLinear; }, get handleInitialize() { return hookRef.current.handleInitialize; }, - get handleUpdate() { return hookRef.current.handleUpdate; }, get handleSaveEnv() { return hookRef.current.handleSaveEnv; }, get handleClaudeSetup() { return hookRef.current.handleClaudeSetup; }, get handleSave() { return hookRef.current.handleSave; }, diff --git a/apps/frontend/src/renderer/components/terminal/useTerminalEvents.ts b/apps/frontend/src/renderer/components/terminal/useTerminalEvents.ts index ded05f23..92c61305 100644 --- a/apps/frontend/src/renderer/components/terminal/useTerminalEvents.ts +++ b/apps/frontend/src/renderer/components/terminal/useTerminalEvents.ts @@ -1,5 +1,6 @@ import { useEffect } from 'react'; import { useTerminalStore } from '../../stores/terminal-store'; +import { terminalBufferManager } from '../../lib/terminal-buffer-manager'; interface UseTerminalEventsOptions { terminalId: string; @@ -20,7 +21,7 @@ export function useTerminalEvents({ useEffect(() => { const cleanup = window.electronAPI.onTerminalOutput((id, data) => { if (id === terminalId) { - useTerminalStore.getState().appendOutput(terminalId, data); + terminalBufferManager.append(terminalId, data); onOutput?.(data); } }); diff --git a/apps/frontend/src/renderer/lib/mocks/project-mock.ts b/apps/frontend/src/renderer/lib/mocks/project-mock.ts index 38f63bd8..b1dded3d 100644 --- a/apps/frontend/src/renderer/lib/mocks/project-mock.ts +++ b/apps/frontend/src/renderer/lib/mocks/project-mock.ts @@ -33,11 +33,6 @@ export const projectMock = { data: { success: true, version: '1.0.0', wasUpdate: false } }), - updateProjectAutoBuild: async () => ({ - success: true, - data: { success: true, version: '1.0.0', wasUpdate: true } - }), - checkProjectVersion: async () => ({ success: true, data: { diff --git a/apps/frontend/src/renderer/stores/project-store.ts b/apps/frontend/src/renderer/stores/project-store.ts index 1aecf74c..5d95d6e1 100644 --- a/apps/frontend/src/renderer/stores/project-store.ts +++ b/apps/frontend/src/renderer/stores/project-store.ts @@ -453,24 +453,3 @@ export async function initializeProject( return null; } } - -/** - * Update auto-claude in a project - */ -export async function updateProjectAutoBuild( - projectId: string -): Promise { - const store = useProjectStore.getState(); - - try { - const result = await window.electronAPI.updateProjectAutoBuild(projectId); - if (result.success && result.data) { - return result.data; - } - store.setError(result.error || 'Failed to update auto-claude'); - return null; - } catch (error) { - store.setError(error instanceof Error ? error.message : 'Unknown error'); - return null; - } -} diff --git a/apps/frontend/src/renderer/stores/terminal-store.ts b/apps/frontend/src/renderer/stores/terminal-store.ts index 5e03779d..92171069 100644 --- a/apps/frontend/src/renderer/stores/terminal-store.ts +++ b/apps/frontend/src/renderer/stores/terminal-store.ts @@ -45,8 +45,6 @@ interface TerminalState { setClaudeMode: (id: string, isClaudeMode: boolean) => void; setClaudeSessionId: (id: string, sessionId: string) => void; setAssociatedTask: (id: string, taskId: string | undefined) => void; - appendOutput: (id: string, data: string) => void; - clearOutputBuffer: (id: string) => void; clearAllTerminals: () => void; setHasRestoredSessions: (value: boolean) => void; @@ -187,18 +185,6 @@ export const useTerminalStore = create((set, get) => ({ })); }, - // DEPRECATED: Use terminalBufferManager.append() directly - // Kept for backward compatibility, but does NOT trigger React re-renders - appendOutput: (id: string, data: string) => { - terminalBufferManager.append(id, data); - // No React state update - this is the key performance improvement! - }, - - // DEPRECATED: Use terminalBufferManager.clear() directly - clearOutputBuffer: (id: string) => { - terminalBufferManager.clear(id); - }, - clearAllTerminals: () => { set({ terminals: [], activeTerminalId: null, hasRestoredSessions: false }); }, diff --git a/apps/frontend/src/shared/constants/ipc.ts b/apps/frontend/src/shared/constants/ipc.ts index 261b3e8e..40c5bde2 100644 --- a/apps/frontend/src/shared/constants/ipc.ts +++ b/apps/frontend/src/shared/constants/ipc.ts @@ -10,7 +10,6 @@ export const IPC_CHANNELS = { PROJECT_LIST: 'project:list', PROJECT_UPDATE_SETTINGS: 'project:updateSettings', PROJECT_INITIALIZE: 'project:initialize', - PROJECT_UPDATE_AUTOBUILD: 'project:updateAutoBuild', PROJECT_CHECK_VERSION: 'project:checkVersion', // Tab state operations (persisted in main process) diff --git a/apps/frontend/src/shared/types/ipc.ts b/apps/frontend/src/shared/types/ipc.ts index 48e69a0e..90ca97bc 100644 --- a/apps/frontend/src/shared/types/ipc.ts +++ b/apps/frontend/src/shared/types/ipc.ts @@ -123,7 +123,6 @@ export interface ElectronAPI { getProjects: () => Promise>; updateProjectSettings: (projectId: string, settings: Partial) => Promise; initializeProject: (projectId: string) => Promise>; - updateProjectAutoBuild: (projectId: string) => Promise>; checkProjectVersion: (projectId: string) => Promise>; // Tab State (persisted in main process for reliability) diff --git a/tests/test_agent_architecture.py b/tests/test_agent_architecture.py index 54262880..1b97d706 100644 --- a/tests/test_agent_architecture.py +++ b/tests/test_agent_architecture.py @@ -303,19 +303,6 @@ class TestElectronToolScoping: class TestSubtaskTerminology: """Verify subtask terminology is used consistently.""" - def test_implementation_plan_uses_subtask_class(self): - """Implementation plan uses Subtask class.""" - impl_plan_path = Path(__file__).parent.parent / "apps" / "backend" / "implementation_plan" / "main.py" - content = impl_plan_path.read_text() - - # Check that it re-exports or imports Subtask and SubtaskStatus - assert "Subtask" in content, ( - "implementation_plan/main.py should reference 'Subtask'" - ) - assert "SubtaskStatus" in content, ( - "implementation_plan/main.py should reference SubtaskStatus enum" - ) - def test_progress_uses_subtask_terminology(self): """Progress module uses subtask terminology.""" progress_path = Path(__file__).parent.parent / "apps" / "backend" / "core" / "progress.py" diff --git a/tests/test_spec_complexity.py b/tests/test_spec_complexity.py index 48b09220..36944477 100644 --- a/tests/test_spec_complexity.py +++ b/tests/test_spec_complexity.py @@ -587,18 +587,6 @@ class TestSaveAssessment: assert "phases_to_run" in data assert "discovery" in data["phases_to_run"] - def test_saves_dev_mode_flag(self, spec_dir: Path): - """Saves dev_mode flag in output.""" - assessment = ComplexityAssessment( - complexity=Complexity.STANDARD, - confidence=0.8, - ) - - save_assessment(spec_dir, assessment, dev_mode=True) - data = json.loads((spec_dir / "complexity_assessment.json").read_text()) - - assert data["dev_mode"] is True - def test_saves_timestamp(self, spec_dir: Path): """Saves created_at timestamp.""" assessment = ComplexityAssessment( diff --git a/tests/test_spec_pipeline.py b/tests/test_spec_pipeline.py index a6778cd9..a606bb31 100644 --- a/tests/test_spec_pipeline.py +++ b/tests/test_spec_pipeline.py @@ -122,17 +122,6 @@ class TestGetSpecsDir: mock_init.assert_called_once_with(temp_dir) - def test_dev_mode_param_ignored(self, temp_dir: Path): - """dev_mode parameter is deprecated and ignored.""" - with patch('spec.pipeline.init_auto_claude_dir') as mock_init: - mock_init.return_value = (temp_dir / ".auto-claude", False) - - result1 = get_specs_dir(temp_dir, dev_mode=False) - result2 = get_specs_dir(temp_dir, dev_mode=True) - - assert result1 == result2 - - class TestSpecOrchestratorInit: """Tests for SpecOrchestrator initialization.""" @@ -574,35 +563,6 @@ class TestComplexityOverride: assert orchestrator.use_ai_assessment is False -class TestSpecOrchestratorDevMode: - """Tests for dev mode configuration.""" - - def test_default_dev_mode_false(self, temp_dir: Path): - """Dev mode is False by default.""" - with patch('spec.pipeline.init_auto_claude_dir') as mock_init: - mock_init.return_value = (temp_dir / ".auto-claude", False) - specs_dir = temp_dir / ".auto-claude" / "specs" - specs_dir.mkdir(parents=True, exist_ok=True) - - orchestrator = SpecOrchestrator(project_dir=temp_dir) - - assert orchestrator.dev_mode is False - - def test_enable_dev_mode(self, temp_dir: Path): - """Can enable dev mode.""" - with patch('spec.pipeline.init_auto_claude_dir') as mock_init: - mock_init.return_value = (temp_dir / ".auto-claude", False) - specs_dir = temp_dir / ".auto-claude" / "specs" - specs_dir.mkdir(parents=True, exist_ok=True) - - orchestrator = SpecOrchestrator( - project_dir=temp_dir, - dev_mode=True, - ) - - assert orchestrator.dev_mode is True - - class TestSpecOrchestratorValidator: """Tests for SpecValidator integration."""