Feat/integration feature files repo#20
Feat/integration feature files repo#20marcocello wants to merge 15 commits intodebuglebowski:mainfrom
Conversation
- Introduced new functions for task feature operations including create, delete, update, and sync from/to repository. - Refactored cleanupTask function to utilize a dedicated cleanupTaskFromData function for better readability and error handling. - Added IPC handlers for managing task features, including syncing and retrieving feature details. - Updated task-related types to include feature management capabilities. - Improved terminal component styling and behavior, ensuring a consistent dark theme. - Removed unused AI description generation code and related types.
- Updated all references from feature.yaml to FEATURE.md in UserSettingsDialog, FeaturePanel, and TaskDetailPage components. - Adjusted related test cases to reflect the new file naming convention. - Modified database handlers to accommodate the change in feature file naming. - Ensured that the application correctly handles the new FEATURE.md format in task-related functionalities.
…ing options in CodeEditor, remove MarkdownPreview, and implement acceptance file handling in FeaturePanel
…ng files and directories
…andling in TaskDetailPage and FeaturePanel
…es and error handling
…cript for better dependency handling
…com/marcocello/SlayZone into feat/integration-feature-files-repo
Additional Comments (1)
Prompt To Fix With AIThis is a comment left during a code review.
Path: packages/domains/file-editor/src/client/Screenshot 2026-03-02 at 16.35.31.png
Line: 1
Comment:
screenshot file accidentally committed - not referenced anywhere in code
How can I resolve this? If you propose a fix, please make it concise. |
| const syncProjectRepoFeaturesSafe = (projectId: string | null | undefined): void => { | ||
| if (!projectId) return | ||
| try { | ||
| syncProjectFeatureTasks(db, projectId) | ||
| } catch (err) { | ||
| console.error(`Failed syncing PRD/spec tasks for project ${projectId}:`, err) |
There was a problem hiding this comment.
syncing on every task read could impact performance with large repos
syncProjectRepoFeaturesSafe scans the filesystem and parses all FEATURE.md files in the project. Called before every getTasks, getTasksByProject, getTask, and getSubTasks operation. With dozens of features, this adds latency to every task read.
Consider:
- caching sync results with TTL
- only syncing on explicit user action or poller interval
- lazy-loading feature metadata on-demand
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/domains/task/src/main/handlers.ts
Line: 387-392
Comment:
syncing on every task read could impact performance with large repos
`syncProjectRepoFeaturesSafe` scans the filesystem and parses all FEATURE.md files in the project. Called before every `getTasks`, `getTasksByProject`, `getTask`, and `getSubTasks` operation. With dozens of features, this adds latency to every task read.
Consider:
- caching sync results with TTL
- only syncing on explicit user action or poller interval
- lazy-loading feature metadata on-demand
How can I resolve this? If you propose a fix, please make it concise.| if (projectChanged) { | ||
| db.prepare('DELETE FROM project_feature_task_links WHERE task_id = ?').run(data.id) | ||
| } |
There was a problem hiding this comment.
moving a task to a different project leaves feature directory orphaned on disk
When projectChanged is true, the link is deleted from the database but deleteFeatureForTask is not called, so the feature directory remains in the old project's repo. Consider whether this is intentional (preserving work) or if cleanup should happen.
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/domains/task/src/main/handlers.ts
Line: 584-586
Comment:
moving a task to a different project leaves feature directory orphaned on disk
When `projectChanged` is true, the link is deleted from the database but `deleteFeatureForTask` is not called, so the feature directory remains in the old project's repo. Consider whether this is intentional (preserving work) or if cleanup should happen.
How can I resolve this? If you propose a fix, please make it concise.| markSkipCache(mainSessionId) | ||
| setTerminalKey((k) => k + 1) | ||
| }, [task, getMainSessionId, resetTaskState]) | ||
|
|
||
| // Inject task description into terminal (no execute) |
There was a problem hiding this comment.
terminal CWD switches to feature directory for codex mode - significant behavioral change
When codex mode is active and feature integration is enabled, the terminal's working directory changes from worktree/project path to the feature directory. This is a notable behavior change that affects where commands run. Consider documenting this or adding a visual indicator in the UI.
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/domains/task/src/client/TaskDetailPage.tsx
Line: 807-811
Comment:
terminal CWD switches to feature directory for codex mode - significant behavioral change
When codex mode is active and feature integration is enabled, the terminal's working directory changes from worktree/project path to the feature directory. This is a notable behavior change that affects where commands run. Consider documenting this or adding a visual indicator in the UI.
How can I resolve this? If you propose a fix, please make it concise.| } | ||
| fs.rmSync(featureDirAbs, { recursive: true, force: true }) |
There was a problem hiding this comment.
uses force: true which suppresses errors if directory doesn't exist
fs.rmSync with force: true silently succeeds even if the directory doesn't exist. This is likely intentional for idempotency, but consider logging when the directory wasn't found for debugging.
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/domains/projects/src/main/repo-feature-sync.ts
Line: 1349-1350
Comment:
uses `force: true` which suppresses errors if directory doesn't exist
`fs.rmSync` with `force: true` silently succeeds even if the directory doesn't exist. This is likely intentional for idempotency, but consider logging when the directory wasn't found for debugging.
How can I resolve this? If you propose a fix, please make it concise.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Summary
This PR adds a feature-first workflow for tasks.
Now, a task can be linked to a project’s
FEATURE.md, and that link is managed in a new Feature tab inside the task view.The main goal is simple: keep tasks and feature docs in sync, so work stays aligned with what is written in the repository.
Objective
FEATURE.mdWhat Changed
Why this matters
This makes feature documentation part of the daily task workflow, instead of something separate. It gives teams one clearer, more consistent way to plan and execute work.
Greptile Summary
This PR introduces a comprehensive feature-first workflow that bidirectionally syncs tasks with
FEATURE.mdfiles in the repository. Tasks can now be linked to feature documents, with updates flowing both ways to keep implementation aligned with documentation.Key Changes
repo-feature-sync.ts, 1368 lines): Scans repository forFEATURE.mdfiles, parses YAML/Markdown frontmatter, creates/updates tasks automatically, and writes task changes back to filesproject_feature_task_linkstable tracks bidirectional sync with content hashing and source trackingStrengths
ensureSchemaBackfillsauto-heals schema drift from external version bumpsPerformance Considerations
Notable Behaviors
terminal_tabs.task_idto support non-persisted repo-based tasksConfidence Score: 4/5
Important Files Changed
project_feature_task_linkstable, removes terminal_tabs FK, includes safety backfills for version driftSequence Diagram
sequenceDiagram participant User participant UI as FeaturePanel / TaskDetailPage participant IPC as Electron IPC participant Handler as Task/Project Handlers participant Sync as repo-feature-sync.ts participant FS as File System participant DB as SQLite Database Note over User,DB: Feature Creation Flow User->>UI: Click "Create FEATURE.md" UI->>IPC: createTaskFeature(taskId, input) IPC->>Handler: db:tasks:createFeature Handler->>Sync: createFeatureForTask(db, taskId) Sync->>DB: Check existing link Sync->>FS: Create feature dir & FEATURE.md Sync->>DB: INSERT project_feature_task_links Sync->>DB: UPDATE tasks SET title Sync-->>Handler: {created: true, featureFilePath} Handler-->>UI: {task, details} UI->>UI: Display feature editor Note over User,DB: Bidirectional Sync: User Edits Feature File User->>UI: Edit FEATURE.md content UI->>UI: Debounce 350ms UI->>IPC: fs.writeFile(projectPath, featureFilePath, content) IPC->>FS: Write file UI->>IPC: syncTaskFeatureFromRepo(taskId) IPC->>Handler: db:tasks:syncFeatureFromRepo Handler->>Sync: syncProjectFeatureTasks(db, projectId) Sync->>FS: Scan & parse FEATURE.md files Sync->>Sync: Calculate content hash Sync->>DB: UPDATE tasks SET title, description Sync->>DB: UPDATE project_feature_task_links Sync-->>Handler: {updated: true, sync} Handler-->>UI: {task, details} Note over User,DB: Bidirectional Sync: User Updates Task User->>UI: Update task title/description UI->>IPC: updateTask({id, title, description}) IPC->>Handler: db:tasks:update Handler->>DB: UPDATE tasks Handler->>Sync: syncTaskToFeatureFile(db, taskId) Sync->>DB: SELECT feature_file_path from links Sync->>FS: Read existing FEATURE.md Sync->>Sync: Upsert frontmatter (id, title, description) Sync->>FS: Write updated FEATURE.md Sync->>DB: UPDATE project_feature_task_links (content_hash, last_sync_source='task') Sync-->>Handler: {updated: true} Handler-->>UI: updated task Note over User,DB: Background Polling (30s interval) loop Every 30 seconds Handler->>Sync: syncAllProjectFeatureTasks(db) Sync->>DB: SELECT projects WHERE feature_repo_integration_enabled=1 loop For each project Sync->>FS: Scan repo for FEATURE.md files Sync->>Sync: Parse frontmatter & calculate hash Sync->>DB: Check existing links by content_hash alt Feature file changed Sync->>DB: UPDATE tasks (title, description) Sync->>DB: UPDATE project_feature_task_links end alt New FEATURE.md found Sync->>DB: INSERT tasks Sync->>DB: INSERT project_feature_task_links end end Sync-->>Handler: {created, updated, errors} Handler->>IPC: Broadcast tasks:changed event end Note over User,DB: Task Deletion with Feature Dir User->>UI: Delete task (checkbox: delete feature dir) UI->>IPC: deleteTask(taskId, {deleteFeatureDir: true}) IPC->>Handler: db:tasks:delete Handler->>Sync: deleteFeatureForTask(db, taskId) Sync->>DB: SELECT feature_file_path from links Sync->>FS: rmSync(featureDirAbs, {recursive: true, force: true}) Sync->>DB: DELETE FROM project_feature_task_links Sync-->>Handler: {deleted: true} Handler->>DB: UPDATE tasks SET deleted_at Handler-->>UI: successLast reviewed commit: 39c0ff0