-
Notifications
You must be signed in to change notification settings - Fork 577
Fix/features completed too soon #777
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
gsxdsm
wants to merge
94
commits into
AutoMaker-Org:main
from
gsxdsm:fix/features-completed-too-soon
Closed
Changes from all commits
Commits
Show all changes
94 commits
Select commit
Hold shift + click to select a range
45f6f17
fix(docker): Pre-install Playwright Chromium browsers for automated t…
Shironex b37a287
fix(docker): Address PR #745 review feedback
Shironex 3ccea7a
fix(docker): Address remaining PR #745 review comments
Shironex aad3ff2
fix(auth): Improve OAuth credential detection and startup warning
Shironex 0aef725
fix(auth): Enhance credential detection logic for OAuth
Shironex 3b361cb
chore: update Codex SDK to version 0.98.0 and add GPT-5.3-Codex model
Shironex 835ffe3
feat: update Claude model to Opus 4.6 and enhance adaptive thinking s…
Shironex f974534
feat: enhance adaptive thinking model support and update UI components
Shironex 220c8e4
feat: add 'dev-server:url-detected' event type to EventType
Shironex 152cf00
docs: map existing codebase
Shironex ef544e7
docs: initialize project
Shironex a0ea65d
chore: ignore planning docs from version control
Shironex 70fc034
test(01-01): add characterization tests for ConcurrencyManager
Shironex b73ef9f
feat(01-01): extract ConcurrencyManager class from AutoModeService
Shironex c92c8e9
refactor(01-01): wire ConcurrencyManager into AutoModeService
Shironex 3bcdc88
feat(01-03): create TypedEventBus class with tests
Shironex bc9dae0
feat(01-02): extract WorktreeResolver from AutoModeService
Shironex 1eb2820
refactor(01-03): wire TypedEventBus into AutoModeService
Shironex 6029e95
feat(01-02): extract FeatureStateManager from AutoModeService
Shironex 18fd1c6
refactor(01-02): wire WorktreeResolver and FeatureStateManager into A…
Shironex 8387b76
feat(02-01): create PlanApprovalService with timeout and recovery
Shironex 58facb1
test(02-01): add PlanApprovalService tests
Shironex 5dca97d
refactor(02-01): wire PlanApprovalService into AutoModeService
Shironex 2fac438
feat(03-01): create SpecParser module with comprehensive tests
Shironex ec5179e
refactor(03-01): wire SpecParser into AutoModeService
Shironex 25fa6fd
feat(03-02): create AgentExecutor class with core streaming logic
Shironex cbb45b6
test(03-02): add AgentExecutor tests
Shironex 8f245e7
refactor(03-02): wire AgentExecutor into AutoModeService
Shironex e3a1c8c
refactor(03-03): wire runAgent() to delegate to AgentExecutor.execute()
Shironex b24839b
test(03-03): add AgentExecutor execution tests
Shironex 4912d37
fix(03-03): fix type compatibility and cleanup unused imports
Shironex ba45587
feat(04-01): create PipelineOrchestrator with step execution and auto…
Shironex 4f00b41
test(04-01): add PipelineOrchestrator unit tests
Shironex 2e577bb
refactor(04-02): wire PipelineOrchestrator into AutoModeService
Shironex 0cd149f
test(04-02): add PipelineOrchestrator delegation and edge case tests
Shironex 7807255
refactor(04-02): remove duplicated pipeline methods from AutoModeService
Shironex 94a8e09
feat(05-01): create AutoLoopCoordinator with loop lifecycle
Shironex 2aa156e
test(05-01): add AutoLoopCoordinator unit tests
Shironex e0f785a
feat(05-02): create ExecutionService with feature execution lifecycle
Shironex 71a0309
test(05-02): add ExecutionService unit tests
Shironex 18624d1
feat(05-03): create RecoveryService with crash recovery logic
Shironex 828d0a0
test(05-03): add RecoveryService unit tests
Shironex 1b39e25
refactor(05-03): wire coordination services into AutoModeService
Shironex afa6039
refactor(05-03): remove duplicated methods from AutoModeService
Shironex 1a7dd5d
refactor(05-03): wire ExecutionService delegation in AutoModeService
Shironex 0383f85
chore(06-01): create facade types and directory structure
Shironex a048462
feat(06-01): create AutoModeServiceFacade with all 23 methods
Shironex 1b32a6b
chore(06-01): create index.ts with exports
Shironex 071af1b
refactor(06-02): migrate Batch 1 query-only routes to facade pattern
Shironex 31f8afc
refactor(06-02): migrate Batch 2 state change routes to facade pattern
Shironex ade22ef
refactor(06-03): migrate Batch 3 feature lifecycle routes to facade p…
Shironex 7bc1f68
refactor(06-03): migrate Batch 4 complex routes to facade pattern
Shironex 7fd3d61
refactor(06-03): migrate Batch 5 secondary routes and wire router index
Shironex 473f935
refactor(06-04): delete auto-mode-service.ts monolith
Shironex efd4284
refactor(06-04): trim 5 oversized services to under 500 lines
Shironex 43309e3
refactor(06-04): extract types and condense agent-executor/pipeline-o…
Shironex 0ed4494
chore(deps): update lint-staged version and change node-gyp repositor…
Shironex df10bcd
fix: lock file
Shironex 28224e1
fix(facade): wire runAgentFn to AgentExecutor.execute
Shironex 49bdaaa
fix(agent-executor): restore wrench emoji in tool output format
Shironex 63b1a35
fix(facade): pass previousContent to AgentExecutor for pipeline steps
Shironex 7c89923
fix: address PR review issues for auto-mode refactor
Shironex 5ffbfb3
fix(server): Address PR #733 review feedback and fix cross-platform t…
Shironex bcc8542
Fix custom providers not passing model name properly
gsxdsm 0f0f515
feat(auto-mode): implement facade caching and enhance error handling
gsxdsm 0745832
refactor(auto-mode): convert getStatusForProject to async and enhance…
gsxdsm 8542a32
refactor(auto-mode): enhance feature retrieval logic in facade and gl…
gsxdsm c703441
chore: update .gitignore to include new configuration files
Shironex 09507bf
Merge branch 'v0.15.0rc' into feat/new-claude-and-codex-models
Shironex 8ed1356
fix: address PR #757 review comments
Shironex 67ebf8c
Merge pull request #757 from AutoMaker-Org/feat/new-claude-and-codex-…
Shironex ad6ce73
Merge remote-tracking branch 'origin/v0.15.0rc' into feature/bug-star…
Shironex d4f68b6
fix: address PR #747 review comments
Shironex 6f1325f
Merge pull request #747 from AutoMaker-Org/feature/bug-startup-warnin…
Shironex d4439fa
Merge branch 'v0.15.0rc' into fix/docker-playwright-missing-browsers
Shironex 8226699
fix(docker): add @playwright/test to server devDependencies
Shironex a08ba1b
fix: address PR #745 review comments
Shironex 1662c6b
Merge pull request #745 from AutoMaker-Org/fix/docker-playwright-miss…
Shironex a3a5c9e
Merge remote-tracking branch 'upstream/v0.15.0rc' into refactor/auto-…
gsxdsm a935229
fix: enhance error handling in feature creation process
gsxdsm f459b73
fix: update kanban card status handling
gsxdsm 41014f6
fix: resolve TypeScript errors after upstream merge
gsxdsm eed5e20
fix(agent-service): fallback to effectiveModel when requestedModel is…
gsxdsm 462dbf1
fix: Address code review comments
gsxdsm 434792a
fix: Normalize 'main' branch to __main__ in auto-loop key generation
gsxdsm 0b03e70
fix: Resolve null coalescing, feature verification, and test abort ha…
gsxdsm ab5d6a0
feat: Improve callback safety and remove unnecessary formatting in au…
gsxdsm 67dd628
test: Add mock for getCurrentBranch in pipeline orchestrator tests
gsxdsm 46dd219
Merge pull request #771 from gsxdsm/refactor/auto-mode-service-gsxdsm
gsxdsm 727a7a5
feat: Exclude waiting_approval cards from active running state display
gsxdsm 2805c0e
Merge pull request #775 from gsxdsm/refactor/auto-mode-service-gsxdsm
gsxdsm 416ef3a
feat: Add error handling to auto-mode facade and implement followUp f…
gsxdsm 4a8c6b0
Update feature-state-manager.test.ts
gsxdsm 30fce3f
test: Update task finalization behavior to keep pending tasks in revi…
gsxdsm File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| # AutoModeService Refactoring | ||
|
|
||
| ## What This Is | ||
|
|
||
| A comprehensive refactoring of the `auto-mode-service.ts` file (5k+ lines) into smaller, focused services with clear boundaries. This is an architectural cleanup of accumulated technical debt from rapid development, breaking the "god object" anti-pattern into maintainable, debuggable modules. | ||
|
|
||
| ## Core Value | ||
|
|
||
| All existing auto-mode functionality continues working — features execute, pipelines flow, merges complete — while the codebase becomes maintainable. | ||
|
|
||
| ## Requirements | ||
|
|
||
| ### Validated | ||
|
|
||
| <!-- Existing functionality that must be preserved --> | ||
|
|
||
| - ✓ Single feature execution with AI agent — existing | ||
| - ✓ Concurrent execution with configurable limits — existing | ||
| - ✓ Pipeline orchestration (backlog → in-progress → approval → verified) — existing | ||
| - ✓ Git worktree isolation per feature — existing | ||
| - ✓ Automatic merging of completed work — existing | ||
| - ✓ Custom pipeline support — existing | ||
| - ✓ Test runner integration — existing | ||
| - ✓ Event streaming to frontend — existing | ||
|
|
||
| ### Active | ||
|
|
||
| <!-- Refactoring goals --> | ||
|
|
||
| - [ ] No service file exceeds ~500 lines | ||
| - [ ] Each service has single, clear responsibility | ||
| - [ ] Service boundaries make debugging obvious | ||
| - [ ] Changes to one service don't risk breaking unrelated features | ||
| - [ ] Test coverage for critical paths | ||
|
|
||
| ### Out of Scope | ||
|
|
||
| - New auto-mode features — this is cleanup, not enhancement | ||
| - UI changes — backend refactor only | ||
| - Performance optimization — maintain current performance, don't optimize | ||
| - Other service refactoring — focus on auto-mode-service.ts only | ||
|
|
||
| ## Context | ||
|
|
||
| **Current state:** `apps/server/src/services/auto-mode-service.ts` is ~5700 lines handling: | ||
|
|
||
| - Worktree management (create, cleanup, track) | ||
| - Agent/task execution coordination | ||
| - Concurrency control and queue management | ||
| - Pipeline state machine (column transitions) | ||
| - Merge handling and conflict resolution | ||
| - Event emission for real-time updates | ||
|
|
||
| **Technical environment:** | ||
|
|
||
| - Express 5 backend, TypeScript | ||
| - Event-driven architecture via EventEmitter | ||
| - WebSocket streaming to React frontend | ||
| - Git worktrees via @automaker/git-utils | ||
| - Minimal existing test coverage | ||
|
|
||
| **Codebase analysis:** See `.planning/codebase/` for full architecture, conventions, and existing patterns. | ||
|
|
||
| ## Constraints | ||
|
|
||
| - **Breaking changes**: Acceptable — other parts of the app can be updated to match new service interfaces | ||
| - **Test coverage**: Currently minimal — must add tests during refactoring to catch regressions | ||
| - **Incremental approach**: Required — can't do big-bang rewrite with everything critical | ||
| - **Existing patterns**: Follow conventions in `.planning/codebase/CONVENTIONS.md` | ||
|
|
||
| ## Key Decisions | ||
|
|
||
| | Decision | Rationale | Outcome | | ||
| | ------------------------- | --------------------------------------------------- | --------- | | ||
| | Accept breaking changes | Allows cleaner interfaces, worth the migration cost | — Pending | | ||
| | Add tests during refactor | No existing safety net, need to build one | — Pending | | ||
| | Incremental extraction | Everything is critical, can't break it all at once | — Pending | | ||
|
|
||
| --- | ||
|
|
||
| _Last updated: 2026-01-27 after initialization_ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,234 @@ | ||
| # Architecture | ||
|
|
||
| **Analysis Date:** 2026-01-27 | ||
|
|
||
| ## Pattern Overview | ||
|
|
||
| **Overall:** Monorepo with layered client-server architecture (Electron-first) and pluggable provider abstraction for AI models. | ||
|
|
||
| **Key Characteristics:** | ||
|
|
||
| - Event-driven communication via WebSocket between frontend and backend | ||
| - Multi-provider AI model abstraction layer (Claude, Cursor, Codex, Gemini, OpenCode, Copilot) | ||
| - Feature-centric workflow stored in `.automaker/` directories | ||
| - Isolated git worktree execution for each feature | ||
| - State management through Zustand stores with API persistence | ||
|
|
||
| ## Layers | ||
|
|
||
| **Presentation Layer (UI):** | ||
|
|
||
| - Purpose: React 19 Electron/web frontend with TanStack Router file-based routing | ||
| - Location: `apps/ui/src/` | ||
| - Contains: Route components, view pages, custom React hooks, Zustand stores, API client | ||
| - Depends on: @automaker/types, @automaker/utils, HTTP API backend | ||
| - Used by: Electron main process (desktop), web browser (web mode) | ||
|
|
||
| **API Layer (Server):** | ||
|
|
||
| - Purpose: Express 5 backend exposing RESTful and WebSocket endpoints | ||
| - Location: `apps/server/src/` | ||
| - Contains: Route handlers, business logic services, middleware, provider adapters | ||
| - Depends on: @automaker/types, @automaker/utils, @automaker/platform, Claude Agent SDK | ||
| - Used by: UI frontend via HTTP/WebSocket | ||
|
|
||
| **Service Layer (Server):** | ||
|
|
||
| - Purpose: Business logic and domain operations | ||
| - Location: `apps/server/src/services/` | ||
| - Contains: AgentService, FeatureLoader, AutoModeService, SettingsService, DevServerService, etc. | ||
| - Depends on: Providers, secure filesystem, feature storage | ||
| - Used by: Route handlers | ||
|
|
||
| **Provider Abstraction (Server):** | ||
|
|
||
| - Purpose: Unified interface for different AI model providers | ||
| - Location: `apps/server/src/providers/` | ||
| - Contains: ProviderFactory, specific provider implementations (ClaudeProvider, CursorProvider, CodexProvider, GeminiProvider, OpencodeProvider, CopilotProvider) | ||
| - Depends on: @automaker/types, provider SDKs | ||
| - Used by: AgentService | ||
|
|
||
| **Shared Library Layer:** | ||
|
|
||
| - Purpose: Type definitions and utilities shared across apps | ||
| - Location: `libs/` | ||
| - Contains: @automaker/types, @automaker/utils, @automaker/platform, @automaker/prompts, @automaker/model-resolver, @automaker/dependency-resolver, @automaker/git-utils, @automaker/spec-parser | ||
| - Depends on: None (types has no external deps) | ||
| - Used by: All apps and services | ||
|
|
||
| ## Data Flow | ||
|
|
||
| **Feature Execution Flow:** | ||
|
|
||
| 1. User creates/updates feature via UI (`apps/ui/src/`) | ||
| 2. UI sends HTTP request to backend (`POST /api/features`) | ||
| 3. Server route handler invokes FeatureLoader to persist to `.automaker/features/{featureId}/` | ||
| 4. When executing, AgentService loads feature, creates isolated git worktree via @automaker/git-utils | ||
| 5. AgentService invokes ProviderFactory to get appropriate AI provider (Claude, Cursor, etc.) | ||
| 6. Provider executes with context from CLAUDE.md files via @automaker/utils loadContextFiles() | ||
| 7. Server emits events via EventEmitter throughout execution | ||
| 8. Events stream to frontend via WebSocket | ||
| 9. UI updates stores and renders real-time progress | ||
| 10. Feature results persist back to `.automaker/features/` with generated agent-output.md | ||
|
|
||
| **State Management:** | ||
|
|
||
| **Frontend State (Zustand):** | ||
|
|
||
| - `app-store.ts`: Global app state (projects, features, settings, boards, themes) | ||
| - `setup-store.ts`: First-time setup wizard flow | ||
| - `ideation-store.ts`: Ideation feature state | ||
| - `test-runners-store.ts`: Test runner configurations | ||
| - Settings now persist via API (`/api/settings`) rather than localStorage (see use-settings-sync.ts) | ||
|
|
||
| **Backend State (Services):** | ||
|
|
||
| - SettingsService: Global and project-specific settings (in-memory with file persistence) | ||
| - AgentService: Active agent sessions and conversation history | ||
| - FeatureLoader: Feature data model operations | ||
| - DevServerService: Development server logs | ||
| - EventHistoryService: Persists event logs for replay | ||
|
|
||
| **Real-Time Updates (WebSocket):** | ||
|
|
||
| - Server EventEmitter emits TypedEvent (type + payload) | ||
| - WebSocket handler subscribes to events and broadcasts to all clients | ||
| - Frontend listens on multiple WebSocket subscriptions and updates stores | ||
|
|
||
| ## Key Abstractions | ||
|
|
||
| **Feature:** | ||
|
|
||
| - Purpose: Represents a development task/story with rich metadata | ||
| - Location: @automaker/types → `libs/types/src/feature.ts` | ||
| - Fields: id, title, description, status, images, tasks, priority, etc. | ||
| - Stored: `.automaker/features/{featureId}/feature.json` | ||
|
|
||
| **Provider:** | ||
|
|
||
| - Purpose: Abstracts different AI model implementations | ||
| - Location: `apps/server/src/providers/{provider}-provider.ts` | ||
| - Interface: Common execute() method with consistent message format | ||
| - Implementations: Claude, Cursor, Codex, Gemini, OpenCode, Copilot | ||
| - Factory: ProviderFactory picks correct provider based on model ID | ||
|
|
||
| **Event:** | ||
|
|
||
| - Purpose: Real-time updates streamed to frontend | ||
| - Location: @automaker/types → `libs/types/src/event.ts` | ||
| - Format: { type: EventType, payload: unknown } | ||
| - Examples: agent-started, agent-step, agent-complete, feature-updated, etc. | ||
|
|
||
| **AgentSession:** | ||
|
|
||
| - Purpose: Represents a conversation between user and AI agent | ||
| - Location: @automaker/types → `libs/types/src/session.ts` | ||
| - Contains: Messages (user + assistant), metadata, creation timestamp | ||
| - Stored: `{DATA_DIR}/agent-sessions/{sessionId}.json` | ||
|
|
||
| **Settings:** | ||
|
|
||
| - Purpose: Configuration for global and per-project behavior | ||
| - Location: @automaker/types → `libs/types/src/settings.ts` | ||
| - Stored: Global in `{DATA_DIR}/settings.json`, per-project in `.automaker/settings.json` | ||
| - Service: SettingsService in `apps/server/src/services/settings-service.ts` | ||
|
|
||
| ## Entry Points | ||
|
|
||
| **Server:** | ||
|
|
||
| - Location: `apps/server/src/index.ts` | ||
| - Triggers: `npm run dev:server` or Docker startup | ||
| - Responsibilities: | ||
| - Initialize Express app with middleware | ||
| - Create shared EventEmitter for WebSocket streaming | ||
| - Bootstrap services (SettingsService, AgentService, FeatureLoader, etc.) | ||
| - Mount API routes at `/api/*` | ||
| - Create WebSocket servers for agent streaming and terminal sessions | ||
| - Load and apply user settings (log level, request logging, etc.) | ||
|
|
||
| **UI (Web):** | ||
|
|
||
| - Location: `apps/ui/src/main.ts` (Vite entry), `apps/ui/src/app.tsx` (React component) | ||
| - Triggers: `npm run dev:web` or `npm run build` | ||
| - Responsibilities: | ||
| - Initialize Zustand stores from API settings | ||
| - Setup React Router with TanStack Router | ||
| - Render root layout with sidebar and main content area | ||
| - Handle authentication via verifySession() | ||
|
|
||
| **UI (Electron):** | ||
|
|
||
| - Location: `apps/ui/src/main.ts` (Vite entry), `apps/ui/electron/main-process.ts` (Electron main process) | ||
| - Triggers: `npm run dev:electron` | ||
| - Responsibilities: | ||
| - Launch local server via node-pty | ||
| - Create native Electron window | ||
| - Bridge IPC between renderer and main process | ||
| - Provide file system access via preload.ts APIs | ||
|
|
||
| ## Error Handling | ||
|
|
||
| **Strategy:** Layered error classification and user-friendly messaging | ||
|
|
||
| **Patterns:** | ||
|
|
||
| **Backend Error Handling:** | ||
|
|
||
| - Errors classified via `classifyError()` from @automaker/utils | ||
| - Classification: ParseError, NetworkError, AuthenticationError, RateLimitError, etc. | ||
| - Response format: `{ success: false, error: { type, message, code }, details? }` | ||
| - Example: `apps/server/src/lib/error-handler.ts` | ||
|
|
||
| **Frontend Error Handling:** | ||
|
|
||
| - HTTP errors caught by api-fetch.ts with retry logic | ||
| - WebSocket disconnects trigger reconnection with exponential backoff | ||
| - Errors shown in toast notifications via `sonner` library | ||
| - Validation errors caught and displayed inline in forms | ||
|
|
||
| **Agent Execution Errors:** | ||
|
|
||
| - AgentService wraps provider calls in try-catch | ||
| - Aborts handled specially via `isAbortError()` check | ||
| - Rate limit errors trigger cooldown before retry | ||
| - Model-specific errors mapped to user guidance | ||
|
|
||
| ## Cross-Cutting Concerns | ||
|
|
||
| **Logging:** | ||
|
|
||
| - Framework: @automaker/utils createLogger() | ||
| - Pattern: `const logger = createLogger('ModuleName')` | ||
| - Levels: ERROR, WARN, INFO, DEBUG (configurable via settings) | ||
| - Output: stdout (dev), files (production) | ||
|
|
||
| **Validation:** | ||
|
|
||
| - File path validation: @automaker/platform initAllowedPaths() enforces restrictions | ||
| - Model ID validation: @automaker/model-resolver resolveModelString() | ||
| - JSON schema validation: Manual checks in route handlers (no JSON schema lib) | ||
| - Authentication: Session token validation via validateWsConnectionToken() | ||
|
|
||
| **Authentication:** | ||
|
|
||
| - Frontend: Session token stored in httpOnly cookie | ||
| - Backend: authMiddleware checks token on protected routes | ||
| - WebSocket: validateWsConnectionToken() for upgrade requests | ||
| - Providers: API keys stored encrypted in `{DATA_DIR}/credentials.json` | ||
|
|
||
| **Internationalization:** | ||
|
|
||
| - Not detected - strings are English-only | ||
|
|
||
| **Performance:** | ||
|
|
||
| - Code splitting: File-based routing via TanStack Router | ||
| - Lazy loading: React.lazy() in route components | ||
| - Caching: React Query for HTTP requests (query-keys.ts defines cache strategy) | ||
| - Image optimization: Automatic base64 encoding for agent context | ||
| - State hydration: Settings loaded once at startup, synced via API | ||
|
|
||
| --- | ||
|
|
||
| _Architecture analysis: 2026-01-27_ |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This entry is a duplicate of the one on line 100 and can be removed to keep the
.gitignorefile clean.