Files
Aperant/apps/backend/implementation_plan/subtask.py
T
Andy 53111dbb95 auto-claude: 147-remove-outdated-compatibility-shims (#1465)
* auto-claude: subtask-1-1 - Remove validation_strategy backward compatibility shim

- Delete apps/backend/validation_strategy.py shim file that re-exported from spec.validation_strategy
- Update docstring in spec/validation_strategy.py to show correct import path

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* auto-claude: subtask-1-2 - Remove service_orchestrator shim

- Deleted apps/backend/service_orchestrator.py backward compatibility shim file
- Updated docstring in services/orchestrator.py to use correct import path
  (from services.orchestrator import instead of from service_orchestrator import)
- Verified no external imports of the shim remain in the codebase
- Import from services.orchestrator works correctly

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* auto-claude: subtask-2-1 - Remove Chunk/ChunkStatus aliases from implementation_plan

Removed backwards compatibility aliases as part of cleaning up outdated
compatibility shims:

- Removed ChunkStatus = SubtaskStatus from enums.py
- Removed Chunk = Subtask from subtask.py
- Removed Chunk/ChunkStatus exports from __init__.py
- Updated all test files to use canonical names (Subtask, SubtaskStatus)

This completes subtasks 2-1, 2-2, and 2-3 together since the test files
depend on all three changes being made atomically.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* auto-claude: subtask-2-4 - Remove deprecated use_orchestrator_review field from GitHub runner models

* auto-claude: subtask-3-1 - Update apps/frontend/src/main/index.ts to use platform imports

* auto-claude: subtask-3-2 - Update python-detector.ts to use platform imports

- Import isWindows from ./platform module
- Replace all process.platform === 'win32' checks with isWindows() calls
- Remove redundant local isWindows variable declarations

* auto-claude: subtask-3-3 - Update apps/frontend/src/main/claude-cli-utils.ts to use platform imports

* auto-claude: subtask-3-4 - Update apps/frontend/src/main/config-paths.ts to use platform imports

* auto-claude: subtask-3-5 - Update apps/frontend/src/main/memory-service.ts to use platform imports

* auto-claude: subtask-4-1 - Update claude-code-handlers.ts to use platform imports

Replace all direct process.platform checks with centralized platform
abstraction functions from ../platform module:
- isWindows() for Windows platform checks
- isMacOS() for macOS/Darwin platform checks
- isLinux() for Linux platform checks

This removes 6 instances of process.platform === '...' comparisons and
1 local isWindows variable assignment, replacing them with the platform
abstraction layer for better cross-platform consistency.

* auto-claude: subtask-4-2 - Update apps/frontend/src/main/ipc-handlers/mcp-handlers.ts to use platform imports

* auto-claude: subtask-4-3 - Update apps/frontend/src/main/ipc-handlers/memory-handlers.ts to use platform imports

- Replace process.platform checks with platform module functions
- Add getOllamaExecutablePaths(), getOllamaInstallCommand(), and getWhichCommand() to platform/paths.ts
- Export new functions from platform/index.ts
- Migrate checkOllamaInstalled() to use platform module for path resolution
- Migrate getOllamaInstallCommand() to delegate to platform module
- Update debug log to use getCurrentOS() instead of process.platform

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* auto-claude: subtask-4-4 - Update apps/frontend/src/main/ipc-handlers/termina

* auto-claude: subtask-4-5 - Update apps/frontend/src/main/ipc-handlers/github/

- Replace direct process.platform check with getWhichCommand() from platform abstraction
- Import getWhichCommand from ../../platform for cross-platform which/where command

* auto-claude: subtask-4-6 - Update apps/frontend/src/main/ipc-handlers/github/utils/subprocess-runner.ts to use platform imports

* auto-claude: subtask-5-1 - Update apps/frontend/src/main/agent/agent-process.ts

Replace direct process.platform checks with platform abstraction:
- Import isWindows from ../platform module
- Replace `process.platform !== 'win32'` with `!isWindows()`
- Replace `process.platform === 'win32'` with `isWindows()`

This ensures consistent platform detection using the centralized
platform abstraction layer.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* auto-claude: subtask-5-2 - Update apps/frontend/src/main/agent/agent-queue.ts

* auto-claude: subtask-5-3 - Update apps/frontend/src/main/terminal/pty-daemon.ts to use platform imports

* auto-claude: subtask-5-4 - Update pty-daemon-client.ts to use platform imports

Replace direct process.platform === 'win32' check with isWindows()
from the platform abstraction layer for consistent cross-platform
handling of socket paths.

* auto-claude: subtask-5-5 - Update apps/frontend/src/main/insights/config.ts to use platform imports

- Import isWindows() from '../platform'
- Replace process.platform === 'win32' checks with isWindows()
- Maintains case-insensitive path comparison on Windows

* auto-claude: subtask-5-6 - Update apps/frontend/src/main/changelog/version-suggester.ts to use platform imports

* auto-claude: subtask-5-7 - Update apps/frontend/src/main/changelog/generator.

* fix: Remove unused import and fix test import paths

- Remove unused `isWindows` import from memory-handlers.ts
- Fix test_service_orchestrator.py to import from services.orchestrator
  instead of the removed service_orchestrator shim
- Fix case sensitivity in path ("Apps" -> "apps")

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Fix test import paths for case sensitivity and removed shims

- Fix path case sensitivity: "Apps" -> "apps" in 21 test files
- Update test_validation_strategy.py to import from spec.validation_strategy

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 12:31:06 +01:00

129 lines
4.4 KiB
Python

#!/usr/bin/env python3
"""
Subtask Models
==============
Defines a single unit of implementation work with tracking, verification,
and output capabilities.
"""
from dataclasses import dataclass, field
from datetime import datetime
from .enums import SubtaskStatus
from .verification import Verification
@dataclass
class Subtask:
"""A single unit of implementation work."""
id: str
description: str
status: SubtaskStatus = SubtaskStatus.PENDING
# Scoping
service: str | None = None # Which service (backend, frontend, worker)
all_services: bool = False # True for integration subtasks
# Files
files_to_modify: list[str] = field(default_factory=list)
files_to_create: list[str] = field(default_factory=list)
patterns_from: list[str] = field(default_factory=list)
# Verification
verification: Verification | None = None
# For investigation subtasks
expected_output: str | None = None # Knowledge/decision output
actual_output: str | None = None # What was discovered
# Tracking
started_at: str | None = None
completed_at: str | None = None
session_id: int | None = None # Which session completed this
# Self-Critique
critique_result: dict | None = None # Results from self-critique before completion
def to_dict(self) -> dict:
"""Convert to dictionary representation."""
result = {
"id": self.id,
"description": self.description,
"status": self.status.value,
}
if self.service:
result["service"] = self.service
if self.all_services:
result["all_services"] = True
if self.files_to_modify:
result["files_to_modify"] = self.files_to_modify
if self.files_to_create:
result["files_to_create"] = self.files_to_create
if self.patterns_from:
result["patterns_from"] = self.patterns_from
if self.verification:
result["verification"] = self.verification.to_dict()
if self.expected_output:
result["expected_output"] = self.expected_output
if self.actual_output:
result["actual_output"] = self.actual_output
if self.started_at:
result["started_at"] = self.started_at
if self.completed_at:
result["completed_at"] = self.completed_at
if self.session_id is not None:
result["session_id"] = self.session_id
if self.critique_result:
result["critique_result"] = self.critique_result
return result
@classmethod
def from_dict(cls, data: dict) -> "Subtask":
"""Create Subtask from dictionary."""
verification = None
if "verification" in data:
verification = Verification.from_dict(data["verification"])
return cls(
id=data["id"],
description=data["description"],
status=SubtaskStatus(data.get("status", "pending")),
service=data.get("service"),
all_services=data.get("all_services", False),
files_to_modify=data.get("files_to_modify", []),
files_to_create=data.get("files_to_create", []),
patterns_from=data.get("patterns_from", []),
verification=verification,
expected_output=data.get("expected_output"),
actual_output=data.get("actual_output"),
started_at=data.get("started_at"),
completed_at=data.get("completed_at"),
session_id=data.get("session_id"),
critique_result=data.get("critique_result"),
)
def start(self, session_id: int):
"""Mark subtask as in progress."""
self.status = SubtaskStatus.IN_PROGRESS
self.started_at = datetime.now().isoformat()
self.session_id = session_id
# Clear stale data from previous runs to ensure clean state
self.completed_at = None
self.actual_output = None
def complete(self, output: str | None = None):
"""Mark subtask as done."""
self.status = SubtaskStatus.COMPLETED
self.completed_at = datetime.now().isoformat()
if output:
self.actual_output = output
def fail(self, reason: str | None = None):
"""Mark subtask as failed."""
self.status = SubtaskStatus.FAILED
self.completed_at = None # Clear to maintain consistency (failed != completed)
if reason:
self.actual_output = f"FAILED: {reason}"