Commit Graph

3 Commits

Author SHA1 Message Date
Haile
a77f213dd5 fix: numerous bugs (#528)
* fix(shell): copy terminal selections from xterm buffer

The shell was delegating Cmd/Ctrl+C to document.execCommand('copy'),
which copied the rendered DOM selection instead of xterm's logical
buffer text. Wrapped values like login URLs could pick up row
whitespace or line breaks and break when pasted.

Route keyboard copy through terminal.getSelection() and the shared
clipboard helper. Also intercept native copy events on the terminal
container so mouse selection and browser copy actions use the same
normalized terminal text.

Remove the copy listener during teardown to avoid leaking handlers
across terminal reinitialization.

* fix(shell): restore terminal focus when switching to the shell tab

Pass shell activity state from MainContent through StandaloneShell and use it
inside Shell to explicitly focus the xterm instance once the terminal is both
initialized and connected.

Previously, switching to the Shell tab left focus on the tab button because
isActive was being ignored and the terminal never called focus() after the tab
activation lifecycle completed. As a result, users had to click inside the
terminal before keyboard input would be accepted.

This change wires isActive through the shell stack, removes the unused prop
handling in Shell, and adds a focus effect that runs when the shell becomes
active and ready. The effect uses both requestAnimationFrame and a zero-delay
timeout so focus is applied reliably after rendering and connection state
updates settle.

This restores immediate typing when opening the shell tab and also improves the
reconnect path by re-focusing the terminal after the shell connection is ready.

* fix(shell): remove fallback command for codex and claude session resumes

The `|| claude` and `|| codex` fallback commands were causing errors as they are not valid commands.

* fix: use fallback while resuming codex and claude sessions for linux and windows

* feat(git): add revert latest local commit action in git panel

Add a complete revert-local-commit flow so users can undo the most recent
local commit directly from the Git header, placed before the refresh icon.

Backend
- add POST /api/git/revert-local-commit endpoint in server/routes/git.js
- validate project input and repository state before executing git operations
- revert latest commit with `git reset --soft HEAD~1` to keep changes staged
- handle initial-commit edge case by deleting HEAD ref when no parent exists
- return clear success and error responses for UI consumption

Frontend
- add useRevertLocalCommit hook to encapsulate API call and loading state
- wire hook into GitPanel and refresh git data after successful revert
- add new toolbar action in GitPanelHeader before refresh icon
- route action through existing confirmation modal flow
- disable action while request is in flight and show activity indicator

Shared UI and typing updates
- extend ConfirmActionType with `revertLocalCommit`
- add confirmation title, label, and style mappings for new action
- render RotateCcw icon for revert action in ConfirmActionModal

Result
- users can safely undo the latest local commit from the UI
- reverted commit changes remain staged for immediate recommit/edit workflows

* fix: run cursor with --trust if workspace trust prompt is detected, and retry once

* fix(git): handle repositories without commits across status and remote flows

Improve git route behavior for repositories initialized with `git init` but with
no commits yet. Previously, several routes called `git rev-parse --abbrev-ref HEAD`,
which fails before the first commit and caused noisy console errors plus a broken
Git panel state.

What changed
- add `getGitErrorDetails` helper to normalize git process failure text
- add `isMissingHeadRevisionError` helper to detect no-HEAD/no-revision cases
- add `getCurrentBranchName` helper:
  - uses `git symbolic-ref --short HEAD` first (works before first commit)
  - falls back to `git rev-parse --abbrev-ref HEAD` for detached HEAD and edge cases
- add `repositoryHasCommits` helper using `git rev-parse --verify HEAD`

Status route improvements
- replace inline branch/HEAD error handling with shared helpers
- keep returning valid branch + `hasCommits: false` for fresh repositories

Remote status improvements
- avoid hard failure when repository has no commits
- return a safe, non-error payload with:
  - `hasUpstream: false`
  - `ahead: 0`, `behind: 0`
  - detected remote name when remotes exist
  - message: "Repository has no commits yet"
- preserve existing upstream detection behavior for repositories with commits

Consistency updates
- switch fetch/pull/push/publish branch lookup to shared `getCurrentBranchName`
  to ensure the same branch-resolution behavior everywhere

Result
- `git init` repositories no longer trigger `rev-parse HEAD` ambiguity failures
- Git panel remains usable before the first commit
- backend branch detection is centralized and consistent across git operations

* fix(git): resolve file paths against repo root for paths with spaces

Fix path resolution for git file operations when project directories include spaces
or when API calls are issued from subdirectories inside a repository.

Problem
- operations like commit/discard/diff could receive file paths that were valid from
  repo root but were executed from a nested cwd
- this produced pathspec errors like:
  - warning: could not open directory '4/4/'
  - fatal: pathspec '4/hello_world.ts' did not match any files

Root cause
- file arguments were passed directly to git commands using the project cwd
- inconsistent path forms (repo-root-relative vs cwd-relative) were not normalized

Changes
- remove unsafe fallback decode in `getActualProjectPath`; fail explicitly when the
  real project path cannot be resolved
- add repository/file-path helpers:
  - `getRepositoryRootPath`
  - `normalizeRepositoryRelativeFilePath`
  - `parseStatusFilePaths`
  - `buildFilePathCandidates`
  - `resolveRepositoryFilePath`
- update file-based git endpoints to resolve paths before executing commands:
  - GET `/diff`
  - GET `/file-with-diff`
  - POST `/commit`
  - POST `/generate-commit-message`
  - POST `/discard`
  - POST `/delete-untracked`
- stage/restore/reset operations now use `--` before pathspecs for safer argument
  separation

Behavioral impact
- git operations now work reliably for repositories under directories containing spaces
- file operations are consistent even when project cwd is a subdirectory of repo root
- endpoint responses continue to preserve existing payload shapes

Verification
- syntax check: `node --check server/routes/git.js`
- typecheck: `npm run typecheck`
- reproduced failing scenario in a temp path with spaces; confirmed root-resolved
  path staging succeeds where subdir-cwd pathspec previously failed

* fix(git-ui): prevent large commit diffs from freezing the history tab

Harden commit diff loading/rendering so opening a very large commit no longer hangs
the browser tab.

Problem
- commit history diff viewer rendered every diff line as a React node
- very large commits could create thousands of nodes and lock the UI thread
- backend always returned full commit patch payloads, amplifying frontend pressure

Backend safeguards
- add `COMMIT_DIFF_CHARACTER_LIMIT` (500,000 chars) in git routes
- update GET `/api/git/commit-diff` to truncate oversized diff payloads
- include `isTruncated` flag in response for observability/future UI handling
- append truncation marker text when server-side limit is applied

Frontend safeguards
- update `GitDiffViewer` to use bounded preview rendering:
  - character cap: 200,000
  - line cap: 1,500
- move diff preprocessing into `useMemo` for stable, one-pass preview computation
- show a clear "Large diff preview" notice when truncation is active

Impact
- commit diff expansion remains responsive even for high-change commits
- UI still shows useful diff content while avoiding tab lockups
- changes apply to shared diff viewer usage and improve resilience broadly

Validation
- `node --check server/routes/git.js`
- `npm run typecheck`
- `npx eslint src/components/git-panel/view/shared/GitDiffViewer.tsx`

* fix(cursor-chat): stabilize first-run UX and clean cursor message rendering

Fix three Cursor chat regressions observed on first message runs:

1. Full-screen UI refresh/flicker after first response.
2. Internal wrapper tags rendered in user messages.
3. Duplicate assistant message on response finalization.

Root causes
- Project refresh from chat completion used the global loading path,
  toggling app-level loading UI.
- Cursor history conversion rendered raw internal wrapper payloads
  as user-visible message text.
- Cursor response handling could finalize through overlapping stream/
  result paths, and stdout chunk parsing could split JSON lines.

Changes
- Added non-blocking project refresh plumbing for chat/session flows.
- Introduced fetch options in useProjectsState (showLoadingState flag).
- Added refreshProjectsSilently() to update metadata without global loading UI.
- Wired window.refreshProjects to refreshProjectsSilently in AppContent.

- Added Cursor user-message sanitization during history conversion.
- Added extractCursorUserQuery() to keep only <user_query> payload.
- Added sanitizeCursorUserMessageText() to strip internal wrappers:
  <user_info>, <agent_skills>, <available_skills>,
  <environment_context>, <environment_info>.
- Applied sanitization only for role === 'user' in
  convertCursorSessionMessages().

- Hardened Cursor backend stream parsing and finalization.
- Added line-buffered stdout parser for chunk-split JSON payloads.
- Flushed trailing unterminated stdout line on process close.
- Removed redundant content_block_stop emission on Cursor result.

- Added frontend duplicate guard in cursor-result handling.
- Skips a second assistant bubble when final result text equals
  already-rendered streamed content.

Code comments
- Added focused comments describing silent refresh behavior,
  tag stripping rationale, duplicate guard behavior, and line buffering.

Validation
- ESLint passes for touched files.
- Production build succeeds.

Files
- server/cursor-cli.js
- src/components/app/AppContent.tsx
- src/components/chat/hooks/useChatRealtimeHandlers.ts
- src/components/chat/utils/messageTransforms.ts
- src/hooks/useProjectsState.ts

---------

Co-authored-by: Haileyesus <something@gmail.com>
Co-authored-by: Simos Mikelatos <simosmik@gmail.com>
2026-03-11 00:16:11 +01:00
Haileyesus
844de26ada Refactor/shared and tasks components (#473)
* refactor: remove unused TasksSettings component

* refactor: migrate TodoList component to a new file with improved structure and normalization logic

* refactor: Move Tooltip and DarkModeToggle to shared/ui

* refactor: Move Tooltip and DarkModeToggle to shared/view/ui

* refactor: move GeminiLogo to llm-logo-provider and update imports

* refactor: remove unused GeminiStatus component

* refactor: move components in src/components/ui to src/shared/view/ui

* refactor: move ErrorBoundary component to main-content/view and update imports

* refactor: move VersionUpgradeModal to its own module

* refactor(wizard): rebuild project creation flow as modular TypeScript components

Replace the monolithic `ProjectCreationWizard.jsx` with a feature-based TS
implementation under `src/components/project-creation-wizard`, while preserving
existing behavior and improving readability, maintainability, and state isolation.

Why:
- The previous wizard mixed API logic, flow state, folder browsing, and UI in one file.
- Refactoring and testing were difficult due to tightly coupled concerns.
- We needed stronger type safety and localized component state.

What changed:
- Deleted:
  - `src/components/ProjectCreationWizard.jsx`
- Added new modular structure:
  - `src/components/project-creation-wizard/index.ts`
  - `src/components/project-creation-wizard/ProjectCreationWizard.tsx`
  - `src/components/project-creation-wizard/types.ts`
  - `src/components/project-creation-wizard/data/workspaceApi.ts`
  - `src/components/project-creation-wizard/hooks/useGithubTokens.ts`
  - `src/components/project-creation-wizard/utils/pathUtils.ts`
  - `src/components/project-creation-wizard/components/*`
    - `WizardProgress`, `WizardFooter`, `ErrorBanner`
    - `StepTypeSelection`, `StepConfiguration`, `StepReview`
    - `WorkspacePathField`, `GithubAuthenticationCard`, `FolderBrowserModal`
- Updated import usage:
  - `src/components/sidebar/view/subcomponents/SidebarModals.tsx`
    now imports from `../../../project-creation-wizard`.

Implementation details:
- Migrated wizard logic to TypeScript using `type` aliases only.
- Kept component prop types colocated in each component file.
- Split responsibilities by feature:
  - container/orchestration in `ProjectCreationWizard.tsx`
  - API/SSE and request parsing in `data/workspaceApi.ts`
  - GitHub token loading/caching behavior in `useGithubTokens`
  - path/URL helpers in `utils/pathUtils.ts`
- Localized UI-only state to child components:
  - folder browser modal state (current path, hidden folders, create-folder input)
  - path suggestion dropdown state with debounced lookup
- Preserved existing UX flows:
  - step navigation and validation
  - existing/new workspace modes
  - optional GitHub clone + auth modes
  - clone progress via SSE
  - folder browsing + folder creation
- Added focused comments for non-obvious logic (debounce, SSE auth constraint, path edge cases).

* refactor(quick-settings): migrate panel to typed feature-based modules

Refactor QuickSettingsPanel from a single JSX component into a modular TypeScript feature structure while preserving behavior and translations.

Highlights:
- Replace legacy src/components/QuickSettingsPanel.jsx with a typed entrypoint (src/components/QuickSettingsPanel.tsx).
- Introduce src/components/quick-settings-panel/ with clear separation of concerns:
  - view/: panel shell, header, handle, section wrappers, toggle rows, and content sections.
  - hooks/: drag interactions and whisper mode persistence.
  - constants.ts and types.ts for shared config and strict local typing.
- Move drag logic into useQuickSettingsDrag with explicit touch/mouse handling, drag threshold detection, click suppression after drag, position clamping, and localStorage persistence.
- Keep user-visible behavior intact:
  - same open/close panel interactions.
  - same mobile/desktop drag behavior and persisted handle position.
  - same quick preference toggles and wiring to useUiPreferences.
  - same hidden whisper section behavior and localStorage/event updates.
- Improve readability and maintainability by extracting repetitive setting rows and section scaffolding into reusable components.
- Add focused comments around non-obvious behavior (drag click suppression, touch scroll lock, hidden whisper section intent).
- Keep files small and reviewable (all new/changed files are under 300 lines).

Validation:
- npm run typecheck
- npm run build

* refactor(quick-settings-panel): restructure QuickSettingsPanel import and create index file

* refactor(shared): move shared ui components to share/view/ui without subfolders

* refactor(LanguageSelector): move LanguageSelector to shared UI components

* refactor(prd-editor): modularize PRD editor with typed feature modules

Break the legacy PRDEditor.jsx monolith into a feature-based TypeScript architecture under src/components/prd-editor while keeping behavior parity and readability.

Key changes:

- Replace PRDEditor.jsx with a typed orchestrator component and a compatibility export bridge at src/components/PRDEditor.tsx.

- Split responsibilities into dedicated hooks: document loading/init, existing PRD registry fetching, save workflow with overwrite detection, and keyboard shortcuts.

- Split UI into focused view components: header, editor/preview body, footer stats, loading state, generate-tasks modal, and overwrite-confirm modal.

- Move filename concerns into utility helpers (sanitize, extension handling, default naming) and centralize template/constants.

- Keep component-local state close to the UI that owns it (workspace controls/modal toggles), while shared workflow state remains in the feature container.

- Reuse the existing MarkdownPreview component for safer markdown rendering instead of ad-hoc HTML conversion.

- Update TaskMasterPanel integration to consume typed PRDEditor directly (remove any-cast) and pass isExisting metadata for correct overwrite behavior.

- Keep all new/changed files below 300 lines and add targeted comments where behavior needs clarification.

Validation:

- npm run typecheck

- npm run build

* refactor(TaskMasterPanel): update PRDEditor import path to match new structure

* refactor(TaskMaster): Remove unused TaskMasterSetupWizard and TaskMasterStatus components

* refactor(TaskDetail): remove unused TaskIndicator import

* refactor(task-master): migrate tasks to a typed feature module

- introduce a new feature-oriented TaskMaster domain under src/components/task-master

- add typed TaskMaster context/provider with explicit project, task, MCP, and loading state handling

- split task UI into focused components (panel, board, toolbar, content, card, detail modal, setup/help modals, banner)

- move task board filtering/sorting/kanban derivation into dedicated hooks and utilities

- relocate CreateTaskModal into the feature module and keep task views modular/readable

- remove legacy monolithic TaskList/TaskDetail/TaskCard files and route main task panel to the new feature panel

- replace contexts/TaskMasterContext.jsx with a typed contexts/TaskMasterContext.ts re-export to the feature context

- update MainContent project sync logic to compare by project name to avoid state churn

- validation: npm run typecheck, npm run build

* refactor(MobileNav): remove unused React import and TaskMasterContext

* refactor(auth): migrate login and setup flows to typed feature module

- Introduce a new feature-based auth module under src/components/auth with clear separation of concerns:\n  - context/AuthContext.tsx for session lifecycle, onboarding status checks, token persistence, and auth actions\n  - view/* components for loading, route guarding, form layout, input fields, and error display\n  - shared auth constants, utility helpers, and type aliases (no interfaces)\n- Convert login and setup UIs to TypeScript and keep form state local to each component for readability and component-level ownership\n- Add explicit API payload typing and safe JSON parsing helpers to improve resilience when backend responses are malformed or incomplete\n- Centralize error fallback handling for auth requests to reduce repeated logic

- Replace legacy auth entrypoints with the new feature module in app wiring:\n  - App now imports AuthProvider and ProtectedRoute from src/components/auth\n  - WebSocketContext, TaskMasterContext, and Onboarding now consume useAuth from the new typed auth context\n- Remove duplicated legacy auth screens (LoginForm.jsx, SetupForm.jsx, ProtectedRoute.jsx)\n- Keep backward compatibility by turning src/contexts/AuthContext.jsx into a thin re-export of the new provider/hook

Result: auth code now follows a feature/domain structure, is fully typed, easier to navigate, and cleaner to extend without touching unrelated UI areas.

* refactor(AppContent): update MobileNav import path and add MobileNav component

* refactor(DiffViewer): rename different diff viewers and place them in different components

* refactor(components): reorganize onboarding/provider auth/sidebar indicator into domain features

- Move onboarding out of root-level components into a dedicated feature module:
  - add src/components/onboarding/view/Onboarding.tsx
  - split onboarding UI into focused subcomponents:
    - OnboardingStepProgress
    - GitConfigurationStep
    - AgentConnectionsStep
    - AgentConnectionCard
  - add onboarding-local types and utils for provider status and validation helpers

- Move multi-provider login modal into a dedicated provider-auth feature:
  - add src/components/provider-auth/view/ProviderLoginModal.tsx
  - add src/components/provider-auth/types.ts
  - keep provider-specific command/title behavior and Gemini setup guidance
  - preserve compatibility for both onboarding flow and settings login flow

- Move TaskIndicator into the sidebar domain:
  - add src/components/sidebar/view/subcomponents/TaskIndicator.tsx
  - update SidebarProjectItem to consume local sidebar TaskIndicator

- Update integration points to the new structure:
  - ProtectedRoute now imports onboarding from onboarding feature
  - Settings now imports ProviderLoginModal directly (remove legacy cast wrapper)
  - git panel consumers now import shared GitDiffViewer by explicit name

- Rename git shared diff view to clearer domain naming:
  - replace shared DiffViewer with shared GitDiffViewer
  - update FileChangeItem and CommitHistoryItem imports accordingly

- Remove superseded root-level legacy components:
  - delete src/components/LoginModal.jsx
  - delete src/components/Onboarding.jsx
  - delete src/components/TaskIndicator.jsx
  - delete old src/components/git-panel/view/shared/DiffViewer.tsx

- Result:
  - clearer feature boundaries (auth vs onboarding vs provider-auth vs sidebar)
  - easier navigation and ownership by domain
  - preserved runtime behavior with improved readability and modularity

* refactor(MainContent): remove TaskMasterPanel import and relocate to task-master component

* fix: update import paths for Input component in FileTree and FileTreeNode

* refactor(FileTree): make file tree context menu a typescript component and move it inside the file tree view

* refactor(FileTree): remove unused ScrollArea import

* feat: setup eslint with typescript and react rules, add unused imports plugin

* fix: remove unused imports, functions, and types after discovering using `npm run lint`

* feat: setup eslint-plugin-react, react-refresh, import-x, and tailwindcss plugins with recommended rules and configurations

* chore: reformat files after running `npm run lint:fix`

* chore: add omments about eslint config plugin uses

* feat: add husky and lint-staged for pre-commit linting

* feat: setup commitlint with conventional config

* fix: i18n translations

---------

Co-authored-by: Haileyesus <something@gmail.com>
Co-authored-by: viper151 <simosmik@gmail.com>
2026-03-05 23:47:58 +01:00
Haileyesus
5e3a7b69d7 Refactor Settings, FileTree, GitPanel, Shell, and CodeEditor components (#402) 2026-02-25 17:07:07 +01:00