Skip to content

feat(webapp): file creation and markdown editing in explorer view#803

Merged
conradkoh merged 41 commits into
release/v1.60.0from
feat/explorer-file-creation-v1.60.0
Jul 4, 2026
Merged

feat(webapp): file creation and markdown editing in explorer view#803
conradkoh merged 41 commits into
release/v1.60.0from
feat/explorer-file-creation-v1.60.0

Conversation

@conradkoh

Copy link
Copy Markdown
Owner

Summary

Add file creation and markdown editing capabilities to the workspace file explorer.

Backlog: ps7ezbmrye942x2x3p9pfmytmh87g00n

Requirements

  • Create new files via the explorer view
  • Edit markdown files in the explorer (other file types remain read-only for now)
  • Markdown: source view (full markdown source) + document editor view
  • Nice-to-haves: Copy as markdown, etc.
  • Save on demand only (Cmd+S / Ctrl+S) — no accidental browser save side effects; scoped to active file window
  • Architecture must handle race conditions between save and latest editing state reaching server/buffer

Test plan

  • Create a new file via explorer
  • Edit markdown in source and document views
  • Cmd+S saves without triggering browser default save
  • Non-markdown files remain read-only
  • pnpm typecheck passes
  • pnpm test passes

Made with Cursor

@vercel

vercel Bot commented Jul 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
chatroom Ready Ready Preview, Comment Jul 4, 2026 11:41pm

conradkoh and others added 7 commits July 4, 2026 04:49
Introduce async file write requests via Convex + daemon subscription,
mirroring the existing file content read path with create/update operations.

Co-authored-by: Cursor <cursoragent@cursor.com>
Wire markdown editing with Cmd+S save, preview pane, and new file creation
using the async workspace write infrastructure from slice 2a.

Co-authored-by: Cursor <cursoragent@cursor.com>
Extend the existing async write request path with operation:'delete',
optional data for create/update only, and daemon unlink fulfillment.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add delete confirmation, folder/file context menus, and shared file-write polling helper.

Co-authored-by: Cursor <cursoragent@cursor.com>
Leave non-terminal I/O failures pending for retry; complete terminal validation errors immediately.

Co-authored-by: Cursor <cursoragent@cursor.com>
Open editor immediately on save; background create confirms via transport; failures toast and close tab.

Co-authored-by: Cursor <cursoragent@cursor.com>
…theme

Support recursive folder delete in the daemon with optimistic UI that hides
descendant paths and closes tabs under the deleted prefix. Split delete into
request/confirm for background polling, and apply chatroom industrial styling
to the New File and delete confirmation modals.

Co-authored-by: Cursor <cursoragent@cursor.com>
conradkoh and others added 2 commits July 4, 2026 04:58
Git ls-files lists index entries missing from disk; subtract --deleted paths
and force refresh via V2 staleness bypass so explorer reflects on-disk deletes.

Co-authored-by: Cursor <cursoragent@cursor.com>
Git enumerates candidates with ignore pruning; fs.access() is the final
arbiter so index-only paths (deleted files, sparse checkout) are excluded.

Co-authored-by: Cursor <cursoragent@cursor.com>
conradkoh and others added 11 commits July 4, 2026 06:21
Centralize always-exclude dirs, secret path denylist, and gitignore batching;
block sensitive file reads in daemon content fulfillment.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add V2 per-dir listing and file search tables with request/sync/query mutations
mirroring the compressed blob pattern from file tree V2.

Co-authored-by: Cursor <cursoragent@cursor.com>
Replace file-tree subscription with reactive dir listing and file search
fulfillment using FS readdir and bounded workspace search.

Co-authored-by: Cursor <cursoragent@cursor.com>
Replace full-tree explorer with per-directory lazy loading, search mode for
filters, and refresh via FILE_EXPLORER_REFRESH_EVENT.

Co-authored-by: Cursor <cursoragent@cursor.com>
Reimplement useWorkspaceFileTree as a thin wrapper over file search with
empty query for workspace-wide autocomplete; update related tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add Convex dir listing integration tests, fix git check-ignore stdin via
spawn, and update daemon subscription test assertions.

Co-authored-by: Cursor <cursoragent@cursor.com>
Replace post-write full-tree syncFileTreeV2 upload with a targeted
syncDirListingV2 for the affected parent directory only.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Consolidate ExplorerTreeNode, search threshold, and tree helpers into
explorer-tree.ts; remove duplicate listing request from useWorkspaceFileListing;
rename listing slot variables and refresh UI copy.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add useDecompressedQueryJson for V2 gzip row decompression; refactor
useDirListing and useFileSearch to parse JSON via useMemo.

Co-authored-by: Cursor <cursoragent@cursor.com>
conradkoh and others added 5 commits July 4, 2026 11:01
Co-authored-by: Cursor <cursoragent@cursor.com>
The panel listener was calling handleRefresh on every refresh event, which
re-dispatched the same event and caused stack overflow on create/delete.

Co-authored-by: Cursor <cursoragent@cursor.com>
…acks

Remove window CustomEvent listeners from panel and explorer components.
Refresh is driven by a parent-owned refreshSignal through useWorkspaceDirExplorer,
with an imperative handle for command-palette refresh.

Co-authored-by: Cursor <cursoragent@cursor.com>
Display "This file is empty." in the markdown editor textarea and
read-only file viewer when a file has no content.

Co-authored-by: Cursor <cursoragent@cursor.com>
fix: gate git file-tree candidates on filesystem existence
conradkoh and others added 16 commits July 4, 2026 16:20
Remove nested ContextMenu roots that caused maximum update depth errors;
use panel-level dropdown menu driven by context target state. Skip redundant
childMap/loadingDirs updates when dir listing data is unchanged.

Co-authored-by: Cursor <cursoragent@cursor.com>
Prevent maximum update depth loops from unstable empty-array and refresh
callback references in dir listing hooks, and add tests covering the
update-loop path plus create/delete refresh orchestration.

Co-authored-by: Cursor <cursoragent@cursor.com>
…h dedup

Add explorer watch registry, UI hot-dir reporting, and daemon debounced fs.watch
so external file changes update listings reactively. Harden against cache churn
with expanded exclusions and content-only dataHash dedup.

Co-authored-by: Cursor <cursoragent@cursor.com>
Use syncDirListingV2Batch when the watcher debounces multiple dir paths so bulk FS changes send one Convex mutation per chunk instead of N sequential syncs.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add integration and unit tests for batch sync dedup, watcher subscription,
and hash-skip paths; fix onRefreshDirs mock types so CLI typecheck passes.

Co-authored-by: Cursor <cursoragent@cursor.com>
Reattach onContextMenu to the scroll container so right-click below the
file tree opens New File, matching pre-refactor ContextMenuTrigger coverage.

Co-authored-by: Cursor <cursoragent@cursor.com>
Defer daemon content fulfillment on ENOENT, ignore transient read-error
cache while create is pending, and show empty/creating UI instead of
[Error reading file] when opening a newly created file.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
When creating a file inside a folder, show a read-only directory prefix
and accept only the file name in the input instead of a full editable path.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add canonical chatroom dialog/alert primitives and shared industrial
surface tokens; migrate new-file, delete confirm, and context menus off
rounded shadcn defaults for consistent light/dark chatroom styling.

Co-authored-by: Cursor <cursoragent@cursor.com>
Radix Dialog overrides HTML autoFocus; use onOpenAutoFocus with an input
ref so the path/filename field is focused when the dialog opens.

Co-authored-by: Cursor <cursoragent@cursor.com>
Extend the file-write pipeline with a rename operation (backend + CLI) and
wire RenameDialog into the explorer context menu, including open tab path
updates when files or folders are renamed.

Co-authored-by: Cursor <cursoragent@cursor.com>
…errors

Add mkdir file-write pipeline (backend + CLI) and New Folder context menu
at root and on folders. Improve errors when outdated daemons cannot handle
rename/mkdir. Extract shared explorer dialog path fields and error helpers.

Co-authored-by: Cursor <cursoragent@cursor.com>
Prevent SessionProvider errors when panel renders NewFolderDialog in unit tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add registered-workspace allowlists, realpath-based path containment, gzip
limits, and spawn-based git/gh argv execution so daemon file ops cannot
escape registered workspaces or interpolate user data into shell strings.

Co-authored-by: Cursor <cursoragent@cursor.com>
feat(workspace): directory-slice sync for file explorer
@conradkoh conradkoh merged commit b11c172 into release/v1.60.0 Jul 4, 2026
2 checks passed
@conradkoh conradkoh mentioned this pull request Jul 4, 2026
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant