diff --git a/.gitignore b/.gitignore index a796abfbab..ff7dafab98 100644 --- a/.gitignore +++ b/.gitignore @@ -68,3 +68,5 @@ Thumbs.db .env .cursor .codex/config.toml + +src/main/appConfig.json \ No newline at end of file diff --git a/docs/.gitignore b/docs/.gitignore deleted file mode 100644 index 906741640e..0000000000 --- a/docs/.gitignore +++ /dev/null @@ -1,22 +0,0 @@ -node_modules - -.DS_Store -.cache -.vercel -.output -.nitro -.next -/build/ -/api/ -/server/build -/public/build -/test-results/ -/playwright-report/ -/blob-report/ -/playwright/.cache/ -.tanstack - -src/routeTree.gen.ts -.source/ -next-env.d.ts -public/md-src/ diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index d219822c4d..0000000000 --- a/docs/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# Emdash - -This is a Tanstack Start application generated with -[Create Fumadocs](https://github.com/fuma-nama/fumadocs). - -Run development server: - -```bash -pnpm run dev -# or -pnpm dev -# or -yarn dev -``` diff --git a/docs/app/[[...slug]]/layout.tsx b/docs/app/[[...slug]]/layout.tsx deleted file mode 100644 index db4f0cf258..0000000000 --- a/docs/app/[[...slug]]/layout.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { DocsLayout } from 'fumadocs-ui/layouts/docs'; -import type { ReactNode } from 'react'; -import { baseOptions } from '@/lib/layout.shared'; -import { source } from '@/lib/source'; - -export default function Layout({ children }: { children: ReactNode }) { - return ( - - {children} - - ); -} diff --git a/docs/app/[[...slug]]/page.tsx b/docs/app/[[...slug]]/page.tsx deleted file mode 100644 index af4996ace4..0000000000 --- a/docs/app/[[...slug]]/page.tsx +++ /dev/null @@ -1,87 +0,0 @@ -import { getGithubLastEdit } from 'fumadocs-core/content/github'; -import defaultMdxComponents from 'fumadocs-ui/mdx'; -import { DocsBody, DocsDescription, DocsPage, DocsTitle } from 'fumadocs-ui/page'; -import type { Metadata } from 'next'; -import { notFound } from 'next/navigation'; -import { CopyMarkdownButton } from '@/components/CopyMarkdownButton'; -import { LastUpdated } from '@/components/LastUpdated'; -import { source } from '@/lib/source'; - -async function getLastModifiedFromGitHub(filePath: string): Promise { - if (process.env.NODE_ENV === 'development') { - return null; - } - - try { - const time = await getGithubLastEdit({ - owner: 'generalaction', - repo: 'emdash', - path: `docs/content/docs/${filePath}.mdx`, - token: process.env.GIT_TOKEN ? `Bearer ${process.env.GIT_TOKEN}` : undefined, - }); - return time ? new Date(time) : null; - } catch { - return null; - } -} - -export default async function Page({ params }: { params: Promise<{ slug?: string[] }> }) { - const { slug } = await params; - const page = source.getPage(slug); - - if (!page) { - notFound(); - } - - const MDX = page.data.body; - - // Prefer plugin-derived lastModified, fallback to GitHub API - let lastModified: Date | undefined = page.data.lastModified; - if (!lastModified) { - const filePath = slug?.join('/') || 'index'; - lastModified = (await getLastModifiedFromGitHub(filePath)) ?? undefined; - } - - return ( - - {page.data.title} - {page.data.description} -
- -
- - - - {lastModified && } -
- ); -} - -export async function generateStaticParams() { - return source.generateParams(); -} - -export async function generateMetadata(props: { - params: Promise<{ slug?: string[] }>; -}): Promise { - const params = await props.params; - const page = source.getPage(params.slug); - - if (!page) notFound(); - - return { - title: page.data.title, - description: page.data.description, - }; -} diff --git a/docs/app/api/search/route.ts b/docs/app/api/search/route.ts deleted file mode 100644 index 97cf05821d..0000000000 --- a/docs/app/api/search/route.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { createFromSource } from 'fumadocs-core/search/server'; -import { source } from '@/lib/source'; - -export const { GET } = createFromSource(source, { - language: 'english', -}); diff --git a/docs/app/global.css b/docs/app/global.css deleted file mode 100644 index b17f8a2e97..0000000000 --- a/docs/app/global.css +++ /dev/null @@ -1,18 +0,0 @@ -@import 'tailwindcss'; -@import 'fumadocs-ui/css/neutral.css'; -@import 'fumadocs-ui/css/preset.css'; - -/* Custom colors from Emdash palette */ -:root { - --color-fd-primary: #c26157; - --color-fd-primary-foreground: #f7fbfc; - --color-fd-accent: #e8ebee; - --color-fd-accent-foreground: #1f2931; -} - -.dark { - --color-fd-primary: #c26157; - --color-fd-primary-foreground: #eef0f2; - --color-fd-accent: #212a2d; - --color-fd-accent-foreground: #eef0f2; -} diff --git a/docs/app/layout.tsx b/docs/app/layout.tsx deleted file mode 100644 index 59df42f33f..0000000000 --- a/docs/app/layout.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import './global.css'; -import { RootProvider } from 'fumadocs-ui/provider/next'; -import type { ReactNode } from 'react'; - -export default function RootLayout({ children }: { children: ReactNode }) { - return ( - - - {children} - - - ); -} - -export const metadata = { - title: 'Emdash - Docs', - description: 'Open source Agentic Development Environment', - icons: { - icon: '/brand/favicon.ico', - }, -}; diff --git a/docs/components/Changelog.tsx b/docs/components/Changelog.tsx deleted file mode 100644 index 8d8ff65487..0000000000 --- a/docs/components/Changelog.tsx +++ /dev/null @@ -1,284 +0,0 @@ -import React from 'react'; - -interface GitHubRelease { - id: number; - tag_name: string; - name: string; - body: string | null; - published_at: string; - html_url: string; - draft: boolean; - prerelease: boolean; -} - -async function getGithubReleases(): Promise { - try { - const response = await fetch('https://api.github.com/repos/generalaction/emdash/releases', { - headers: { - Accept: 'application/vnd.github.v3+json', - ...(process.env.GITHUB_TOKEN && { - Authorization: `token ${process.env.GITHUB_TOKEN}`, - }), - }, - next: { revalidate: 3600 }, // Cache for 1 hour - }); - - if (!response.ok) { - console.error('GitHub API error:', response.status); - return []; - } - - const releases = await response.json(); - return releases.filter((r: GitHubRelease) => !r.draft); - } catch (error) { - console.error('Failed to fetch releases:', error); - return []; - } -} - -function formatDate(dateString: string): string { - const date = new Date(dateString); - return date.toLocaleDateString('en-US', { - year: 'numeric', - month: 'long', - day: 'numeric', - }); -} - -function formatVersion(tagName: string): string { - return tagName.startsWith('v') ? tagName.substring(1) : tagName; -} - -export async function Changelog() { - const releases = await getGithubReleases(); - - if (releases.length === 0) { - return ( -
-

- No releases found. Check the{' '} - - GitHub Releases - {' '} - page. -

-
- ); - } - - return ( -
- {releases.slice(0, 20).map((release) => ( -
-
-

- - v{formatVersion(release.tag_name)} - -

- -
- - {release.body ? ( -
- -
- ) : ( -

No release notes available.

- )} -
- ))} -
- ); -} - -function ReleaseNotes({ content }: { content: string }) { - // Process content line by line, handling both markdown and HTML - const lines = content.split('\n'); - const elements: React.ReactNode[] = []; - let currentListItems: React.ReactNode[] = []; - let inCodeBlock = false; - let codeBlockContent: string[] = []; - let codeBlockStartIndex = 0; - - // Helper function to flush list items - const flushListItems = () => { - if (currentListItems.length > 0) { - elements.push( -
    - {currentListItems} -
- ); - currentListItems = []; - } - }; - - // Helper function to process links in text - const processLinks = (text: string): string => { - return ( - text - // Handle GitHub URLs, but not if they're followed by punctuation - .replace( - /https:\/\/github\.com\/[^\s\)\]]+/g, - (url) => - `${url.replace(/[.,;!?]+$/, '')}` - ) - // Handle @mentions, but avoid matching email addresses - // Look for @mentions that are preceded by whitespace or start of string - .replace( - /(^|[\s\(])@(\w+)(?=\s|$|[^\w@])/g, - (match, prefix, username) => - `${prefix}@${username}` - ) - ); - }; - - for (let i = 0; i < lines.length; i++) { - const line = lines[i]; - - // Check for code block start/end - if (line.startsWith('```')) { - if (inCodeBlock) { - // End code block - elements.push( -
-            {codeBlockContent.join('\n')}
-          
- ); - codeBlockContent = []; - inCodeBlock = false; - } else { - // Start code block - flushListItems(); // Flush any pending list items - inCodeBlock = true; - codeBlockStartIndex = i; - } - continue; - } - - // If we're in a code block, just collect the content - if (inCodeBlock) { - codeBlockContent.push(line); - continue; - } - - // Handle HTML img tags - if (line.includes(']+>/); - if (imgMatch) { - const srcMatch = imgMatch[0].match(/src="([^"]+)"/); - const altMatch = imgMatch[0].match(/alt="([^"]+)"/); - const widthMatch = imgMatch[0].match(/width="([^"]+)"/); - const heightMatch = imgMatch[0].match(/height="([^"]+)"/); - - if (srcMatch) { - elements.push( -
- {altMatch -
- ); - continue; - } - } - } - - // Headers - if (line.startsWith('## ')) { - flushListItems(); // Flush any pending list items - elements.push( -

- {line.substring(3)} -

- ); - continue; - } - if (line.startsWith('### ')) { - flushListItems(); // Flush any pending list items - elements.push( -

- {line.substring(4)} -

- ); - continue; - } - - // List items (support both * and - prefixes) - if (line.startsWith('* ') || line.startsWith('- ')) { - const item = line.substring(2); - const withLinks = processLinks(item); - currentListItems.push(
  • ); - continue; - } - - // If we hit a non-list item, flush any pending list items - if (currentListItems.length > 0 && !line.startsWith(' ')) { - flushListItems(); - } - - // Bold text (like **New Contributors**) - if (line.includes('**')) { - flushListItems(); // Flush any pending list items - const formatted = line.replace(/\*\*(.*?)\*\*/g, '$1'); - const withLinks = processLinks(formatted); - elements.push( -

    - ); - continue; - } - - // Full Changelog link - if (line.includes('Full Changelog:')) { - flushListItems(); // Flush any pending list items - const match = line.match(/https:\/\/github\.com\/[^\s\)\]]+/); - if (match) { - elements.push( -

    - Full Changelog:{' '} - - View diff - -

    - ); - continue; - } - } - - // Empty lines - if (line.trim() === '') { - flushListItems(); // Flush any pending list items - continue; - } - - // Regular text with link processing - flushListItems(); // Flush any pending list items - const withLinks = processLinks(line); - elements.push(

    ); - } - - // Flush any remaining list items - flushListItems(); - - return <>{elements}; -} diff --git a/docs/components/CopyMarkdownButton.tsx b/docs/components/CopyMarkdownButton.tsx deleted file mode 100644 index f6d8fc0e26..0000000000 --- a/docs/components/CopyMarkdownButton.tsx +++ /dev/null @@ -1,31 +0,0 @@ -'use client'; - -import * as React from 'react'; - -export function CopyMarkdownButton({ markdownUrl }: { markdownUrl: string }) { - const [state, setState] = React.useState<'idle' | 'copied' | 'error'>('idle'); - - async function onCopy() { - try { - setState('idle'); - const res = await fetch(markdownUrl, { cache: 'no-store' }); - if (!res.ok) throw new Error(`Failed to fetch markdown: ${res.status}`); - const md = await res.text(); - await navigator.clipboard.writeText(md); - setState('copied'); - window.setTimeout(() => setState('idle'), 1200); - } catch { - setState('error'); - window.setTimeout(() => setState('idle'), 1500); - } - } - - return ( - - ); -} diff --git a/docs/components/LastUpdated.tsx b/docs/components/LastUpdated.tsx deleted file mode 100644 index b0670491ad..0000000000 --- a/docs/components/LastUpdated.tsx +++ /dev/null @@ -1,19 +0,0 @@ -export function LastUpdated({ date }: { date: Date }) { - if (!date || isNaN(date.getTime())) { - return null; - } - - const formatted = new Intl.DateTimeFormat(undefined, { - year: 'numeric', - month: 'long', - day: 'numeric', - }).format(date); - - return ( -

    -
    - Last updated on {formatted} -
    -
    - ); -} diff --git a/docs/content/docs/best-of-n.mdx b/docs/content/docs/best-of-n.mdx deleted file mode 100644 index 5c730617f8..0000000000 --- a/docs/content/docs/best-of-n.mdx +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: Best of N -description: Run multiple agents in parallel and pick the best result ---- - -Run multiple agents on the same task, let them work in parallel, then pick the best output. Each agent gets its own worktree so they don't interfere with each other. - -Running multiple agents in parallel - -## Why Use It - -Different agents have different strengths. Running them in parallel lets you: - -- Compare solutions from different providers (Claude vs Codex vs Gemini) -- Get multiple attempts at a tricky problem -- Race agents to see which finishes first - -## How to Start - -When creating a task: - -1. Click the provider dropdown -2. Select multiple providers, or increase the count for a single provider (e.g., 3× Claude Code) -3. Click Create - -Emdash creates a separate git branch and worktree for each agent. They all start from the same base commit but work independently. - -Multiple agents working in separate worktrees - -## Working with Multiple Agents - -Each agent spawns in its own terminal tab. Switch between tabs to watch them work, or use the shared input bar to send the same message to all of them. - -## Comparing Results - -After agents finish, review their changes in the [diff view](/diff-view). Each agent's worktree has its own set of changes. Check the diff stats (files changed, lines added/removed) for a quick sense of each approach. - -Pick the best solution and merge that branch. Discard the rest. - -## Tips - -- Start with 2-3 agents. More than that gets hard to compare. -- Use the same initial prompt for fair comparison. -- Complex tasks benefit most from multiple perspectives. diff --git a/docs/content/docs/changelog.mdx b/docs/content/docs/changelog.mdx deleted file mode 100644 index 1a0eec111a..0000000000 --- a/docs/content/docs/changelog.mdx +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: Changelog -description: Version history and release notes for Emdash ---- - -import { Changelog } from '../../components/Changelog'; - - - ---- - -## Release Process - -Emdash follows [Semantic Versioning](https://semver.org/): - -- **Patch versions** (0.0.x): Bug fixes and minor improvements -- **Minor versions** (0.x.0): New features and capabilities -- **Major versions** (x.0.0): Breaking changes - -## Contributing - -See our [Contributing Guide](/contributing) to learn how you can help improve Emdash. diff --git a/docs/content/docs/ci-checks.mdx b/docs/content/docs/ci-checks.mdx deleted file mode 100644 index ad892b4389..0000000000 --- a/docs/content/docs/ci-checks.mdx +++ /dev/null @@ -1,57 +0,0 @@ ---- -title: CI/CD Checks -description: Monitor GitHub Actions check runs directly in Emdash ---- - -Emdash surfaces your GitHub Actions CI/CD status inside the app so you can monitor check runs without switching to a browser. - -CI/CD checks panel in Emdash - -## Viewing Checks - -Once a task has a Pull Request, a **Checks** tab appears in the file changes panel. Click it to see all check runs for that PR's branch. - -Each check shows: - -- **Status**: Green checkmark (pass), red X (fail), amber spinner (pending), or grey dash (skipped/cancelled) -- **Name and workflow**: Which check ran and from which workflow -- **Duration**: How long the check took -- **External link**: Click to open the full check run on GitHub - -A summary at the top shows the total count of passed, failed, and pending checks. - -## Auto-Refresh - -Emdash automatically polls for check updates: - -- **Every 10 seconds** while checks are still running -- **Every 60 seconds** once all checks complete -- **On window focus** — checks refresh when you switch back to Emdash - -Polling pauses when the app is in the background to save resources. - -## Requirements - -- The [GitHub CLI](https://cli.github.com/) (`gh`) must be installed and authenticated -- The task's branch must have an open Pull Request on GitHub -- Your repository must have GitHub Actions workflows configured - -If the Checks tab is disabled, it means no PR exists for the current task yet. Push a branch and open a PR to start seeing checks. - -## Tips - -- The Checks tab automatically activates when a PR exists but there are no local uncommitted changes. -- Failed checks show a red dot on the tab badge so you can spot failures at a glance. -- A spinning indicator on the tab badge means checks are still in progress. -- Click the external link icon on any check to jump straight to the run details on GitHub. diff --git a/docs/content/docs/contributing.mdx b/docs/content/docs/contributing.mdx deleted file mode 100644 index d78e6a5f28..0000000000 --- a/docs/content/docs/contributing.mdx +++ /dev/null @@ -1,189 +0,0 @@ ---- -title: Contributing -description: Help improve Emdash - contribution guidelines and development setup ---- - -Thanks for your interest in contributing! We favor small, focused PRs and clear intent over big bangs. This guide explains how to get set up, the workflow we use, and a few project‑specific conventions. - -## Quick Start - -### Prerequisites - -- **Node.js 20.0.0+ (recommended: 22.20.0)** and Git -- Optional (recommended for end‑to‑end testing): - - GitHub CLI (`brew install gh`; then `gh auth login`) - - At least one supported coding agent CLI (see [Providers](/providers)) - -### Setup - -```bash -# Fork this repo, then clone your fork -git clone https://github.com//emdash.git -cd emdash - -# Use the correct Node.js version (if using nvm) -nvm use - -# Quick start: install dependencies and run dev server -pnpm run d - -# Or run separately: -pnpm install -pnpm run dev - -# Type checking, lint, build -pnpm run typecheck -pnpm run lint -pnpm run build -``` - -**Tip:** During development, the renderer hot‑reloads. Changes to the Electron main process (files in `src/main`) require a restart of the dev app. - -## Project Overview - -- `src/main/` – Electron main process, IPC handlers, services (Git, worktrees, PTY manager, DB, etc.) -- `src/renderer/` – React UI (Vite), hooks, components -- Local database – SQLite file created under the OS userData folder (see "Local DB" below) -- Worktrees – Git worktrees are created outside your repo root in a sibling `worktrees/` folder -- Logs – Agent terminal output and app logs are written to the OS userData folder (not inside repos) - -## Development Workflow - -### 1. Create a feature branch - -```bash -git checkout -b feat/ -``` - -### 2. Make changes and keep PRs small and focused - -- Prefer a series of small PRs over one large one. -- Include UI screenshots/GIFs when modifying the interface. -- Update docs (README or inline help) when behavior changes. - -### 3. Run checks locally - -```bash -pnpm run format # Format code with Prettier (required) -pnpm run typecheck # TypeScript type checking -pnpm run lint # ESLint -pnpm run build # Build both main and renderer -``` - -Pre-commit hooks run automatically via Husky + lint-staged. On each commit, staged files are auto-formatted with Prettier and linted with ESLint. You don't need to remember to run these manually. Type checking and tests run in CI only since they need the full project context and are slower to execute. - -If you need to skip the hook for a work-in-progress commit, use `git commit --no-verify`. The checks will still run in CI when you open a PR. - -### 4. Commit using Conventional Commits - -- `feat:` – new user‑facing capability -- `fix:` – bug fix -- `chore:`, `refactor:`, `docs:`, `perf:`, `test:` etc. - -**Examples:** - -``` -fix(opencode): change initialPromptFlag from -p to --prompt for TUI - -feat(docs): add changelog tab with GitHub releases integration -``` - -### 5. Open a Pull Request - -- Describe the change, rationale, and testing steps. -- Link related Issues. -- Keep the PR title in Conventional Commit format if possible. - -## Code Style and Patterns - -### TypeScript + ESLint + Prettier - -Pre-commit hooks handle formatting and linting automatically on staged files. For full-project checks you can run them manually: - -- `pnpm run format` -- format all files with Prettier -- `pnpm run typecheck` -- TypeScript type checking (whole project) -- `pnpm run lint` -- ESLint across all files -- `pnpm exec vitest run` -- run the test suite - -### Electron main (Node side) - -- Prefer `execFile` over `exec` to avoid shell quoting issues. -- Never write logs into Git worktrees. All logs belong in the Electron `userData` folder. -- Be conservative with console logging; noisy logs reduce signal. Use clear prefixes. - -### Git and worktrees - -- The app creates worktrees in a sibling `../worktrees/` folder. -- Do not delete worktree folders from Finder/Explorer; if you need cleanup, use: - - `git worktree prune` (from the main repo) - - or the in‑app workspace removal - -### Documentation - -When writing or updating docs, keep the tone clear and conversational. Use complete sentences and natural language rather than long bullet point lists. Avoid em dashes (—); use commas, periods, or rephrase instead. - -### Renderer (React) - -- Components live under `src/renderer/components`; hooks under `src/renderer/hooks`. -- Agent CLIs are embedded via terminal emulation (xterm.js) - each agent runs in its own PTY. -- Use existing UI primitives and Tailwind utility classes for consistency. -- Aim for accessible elements (labels, `aria-*` where appropriate). - -### Local DB (SQLite) - -**Location** (Electron `app.getPath('userData')`): - -- macOS: `~/Library/Application Support/emdash/emdash.db` -- Linux: `~/.config/emdash/emdash.db` -- Windows: `%APPDATA%\emdash\emdash.db` - -**Reset:** quit the app, delete the file, relaunch (the schema is recreated). - -## Issue Reports and Feature Requests - -Use GitHub Issues. Include: - -- OS, Node version -- Steps to reproduce -- Relevant logs (renderer console, terminal output) -- Screenshots/GIFs for UI issues - -## Release Process (maintainers) - -Use pnpm's built-in versioning to ensure consistency: - -```bash -# For bug fixes (0.2.9 → 0.2.10) -pnpm version patch - -# For new features (0.2.9 → 0.3.0) -pnpm version minor - -# For breaking changes (0.2.9 → 1.0.0) -pnpm version major -``` - -This automatically: - -1. Updates `package.json` and `pnpm-lock.yaml` -2. Creates a git commit with the version number (e.g., `"0.2.10"`) -3. Creates a git tag (e.g., `v0.2.10`) - -Then push to trigger the CI/CD pipeline. - -### What happens next - -Two GitHub Actions workflows trigger on version tags: - -**macOS Release** (`.github/workflows/release.yml`): - -1. Builds the TypeScript and Vite bundles -2. Signs the app with Apple Developer ID -3. Notarizes via Apple's notary service -4. Creates a GitHub Release with DMG artifacts for arm64 and x64 - -**Linux/Nix Build** (`.github/workflows/nix-build.yml`): - -1. Computes the correct dependency hash from `pnpm-lock.yaml` -2. Builds the x86_64-linux package via Nix flake -3. Pushes build artifacts to Cachix diff --git a/docs/content/docs/diff-view.mdx b/docs/content/docs/diff-view.mdx deleted file mode 100644 index 8c8ad22d8d..0000000000 --- a/docs/content/docs/diff-view.mdx +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: Diff View -description: Review and manage code changes ---- - -The diff view shows all file changes in a task's worktree. Stage files, review diffs, write commit messages, and create pull requests from one panel. - -Diff view interface in Emdash - -## Where to Find It - -The diff view lives in the right sidebar when you have a task open. It updates automatically as the agent makes changes (polls every 5 seconds). - -## What You See - -For each changed file: - -- File path and type icon -- Lines added (green) and removed (red) -- Staged or unstaged status - -The header shows total files changed, overall additions/deletions, and PR status if a pull request exists. - -## Actions - -**Stage a file**: Click the + icon to add a file to the staging area. - -**Unstage or revert**: Click the undo icon. For staged files, this unstages them. For unstaged files, this discards all changes (resets to last commit). - -**View diff**: Click a file to open it in the diff viewer. You can edit the file directly in the diff view and save your changes. - -**View all changes**: Click "View All" to see diffs for every changed file in one scrollable view. - -**Commit and push**: Type a commit message and press Enter. Emdash commits staged changes and pushes to the branch. - -**Create PR**: After pushing, a "Create PR" button appears if your branch is ahead of main. - -## Inline Editing - -The diff viewer isn't read-only. Edit the modified version directly, then save. This is useful for quick fixes without switching to your editor. diff --git a/docs/content/docs/file-editor.mdx b/docs/content/docs/file-editor.mdx deleted file mode 100644 index 3243aa564a..0000000000 --- a/docs/content/docs/file-editor.mdx +++ /dev/null @@ -1,55 +0,0 @@ ---- -title: File Editor -description: Edit files directly in Emdash ---- - -The file editor lets you browse and edit code in a task's worktree without switching to an external editor. Use it to explore the codebase, make edits yourself, or review what an agent has done. - -File editor interface in Emdash - -## Opening the Editor - -Click the code icon in the titlebar when viewing a task. The editor opens in a side panel with a file tree on the left and the code editor on the right. - -## Navigating Files - -The left panel shows your project's file tree. Click a file to open it. Files open in tabs at the top of the editor, so you can switch between multiple files. - -Common system directories like `node_modules`, `.git`, and build output are hidden by default. Click the eye icon to show or hide them. - -## Editing - -The editor is a full-featured code editor with syntax highlighting, find/replace, and the usual keyboard shortcuts. Changes auto-save after 2 seconds of inactivity, or press `⌘S` to save immediately. - -Git diff markers appear in the gutter: - -- Green dots for added lines -- Orange dots for modified lines -- Red markers for deleted lines - -These update automatically as you edit, so you can see what's changed compared to the last commit. - -## Saving - -Files with unsaved changes show a dot in their tab. Use `⌘⇧S` to save all open files at once, or click "Save All" in the header. - -After saving, the [diff view](/diff-view) updates to reflect your changes. - -## Images - -The editor also handles images. Click an image file to preview it instead of showing raw bytes. - -## Resizing - -Drag the divider between the file tree and editor to adjust panel widths. The layout remembers your preference. diff --git a/docs/content/docs/index.mdx b/docs/content/docs/index.mdx deleted file mode 100644 index b1caebf069..0000000000 --- a/docs/content/docs/index.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Emdash Overview -description: An Open Source Agentic Development Environment (ADE) ---- - -Emdash is an open source desktop app for running multiple coding agents in parallel. Each agent works in an isolated Git worktree, so they don't interfere with each other. - -## Capabilities - -- **[Parallel agents](/parallel-agents):** Run multiple agents simultaneously, each in its own worktree -- **[Provider support](/providers):** Use any of 18+ CLI-based agents: Claude Code, Codex, Gemini, OpenCode, and more -- **[Best-of-N](/best-of-n):** Run multiple agents on the same task and pick the best result -- **[Diff view](/diff-view):** Review changes across agents side-by-side -- **[Kanban view](/kanban-view):** Organize tasks visually across your workflow -- **[Issue integration](/issues):** Pull tasks from Linear, Jira, or GitHub Issues directly - -## How It Works - -Click "Add Task" to create one or more worktrees. Each worktree runs its own agent. You can then review the diff when done, iterate if needed, and open a PR inside of Emdash. - -## Demo - -