diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..d4c25af --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,265 @@ +# Contributing to Local History Restore + +Thank you for your interest in contributing to the Local History Restore extension! This guide will help you get started with development. + +## Development Setup + +### Prerequisites + +- Node.js 16+ (20 recommended) +- npm +- VS Code + +### Getting Started + +1. Clone the repository: +```bash +git clone https://github.com/minouris/vscode-restore-folder.git +cd vscode-restore-folder +``` + +2. Install dependencies: +```bash +npm install +``` + +3. Build the TypeScript code: +```bash +npm run compile +``` + +4. Open the project in VS Code and press `F5` to start debugging + +## Project Structure + +``` +├── src/ +│ ├── backup-scanner.ts # Discovers deleted items from VS Code history +│ ├── deleted-items-provider.ts # TreeDataProvider for Explorer view +│ ├── item-organizer.ts # Organizes items into hierarchical structure +│ ├── file-restorer.ts # Handles file/folder restoration logic +│ ├── file-watcher-manager.ts # Manages file system watchers +│ ├── file-system-utils.ts # File system operation helpers +│ ├── extension.ts # Main extension entry point +│ └── test/ # Unit tests +├── test/helpers/vscode/ # Minimal vscode stub for testing +├── package.json # Extension manifest +└── tsconfig.json # TypeScript configuration +``` + +## Development Workflow + +### Compiling + +The extension is written in TypeScript and must be compiled to JavaScript: + +```bash +npm run compile +``` + +For continuous compilation during development: + +```bash +npm run watch +``` + +**Note**: Unit tests run via ts-node and do not require compilation during development. + +### Running Tests + +This project uses Mocha + Chai + Sinon for testing. Tests run in Node.js using a minimal VS Code stub. + +Run all unit tests: +```bash +npm run test:unit +# or with NODE_PATH explicitly: +NODE_PATH=./test/helpers mocha -r ts-node/register 'src/test/**/*.ts' --exit +``` + +Run tests with coverage: +```bash +npm run test:cov +# or: +NODE_PATH=./test/helpers c8 mocha -r ts-node/register 'src/test/**/*.ts' +``` + +### Testing Notes + +- Tests use `mock-fs` to avoid touching the real filesystem +- The `test/helpers/vscode` directory provides a minimal VS Code API stub +- Tests set up fake workspace folders via `vscode.workspace.workspaceFolders` +- If tests fail with "vscode not found", ensure `NODE_PATH=./test/helpers` is set + +### Linting + +```bash +npm run lint +``` + +## Key Modules + +### backup-scanner.ts +Discovers entries in VS Code's local history directory and creates `DeletedItem` records. Scans the backup directory structure and identifies files that no longer exist in the workspace. + +### deleted-items-provider.ts +Implements `TreeDataProvider` to expose deleted items in the Explorer view. Manages tree state, refresh operations, and provides data to VS Code's tree view API. + +### item-organizer.ts +Transforms flat lists of deleted items into a hierarchical tree structure, organizing files by their folder paths for better visualization. + +### file-restorer.ts +Contains logic to restore files and folders: +- Single file restoration from backups +- Empty directory creation +- Recursive folder restoration with all contents + +### file-watcher-manager.ts +Creates and manages `FileSystemWatcher` instances with debounced refresh capabilities. Monitors the workspace for file deletions and triggers view updates. + +### file-system-utils.ts +Small helper utilities for: +- File system operations (reading, checking existence) +- URI normalization and path handling +- Cross-platform compatibility + +## Building & Packaging + +### Creating a VSIX Package + +To package the extension for distribution: + +```bash +npm run package +``` + +Or manually: +```bash +npm run compile +npx vsce package +``` + +This creates a `.vsix` file that can be: +- Installed locally in VS Code +- Published to the VS Code Marketplace +- Shared with others for testing + +### Publishing + +Publishing requires: +1. A Visual Studio Marketplace publisher account +2. A Personal Access Token (PAT) + +To publish: +```bash +npx vsce publish --pat YOUR_PAT +``` + +For CI-based publishing, see the GitHub Actions workflow in `.github/workflows/`. + +## Development Environment + +### Devcontainer + +The project includes a devcontainer configuration for development in containerized environments. + +#### Corporate TLS/Proxy Setup + +If developing behind a corporate proxy or TLS-intercepting proxy (e.g., Zscaler): + +**Option 1: Build-time CA Installation** +1. Place CA certificate files in `.devcontainer/certs/` +2. Build the container - certificates are automatically installed + +```bash +mkdir -p .devcontainer/certs +cp /path/to/corporate-ca.pem .devcontainer/certs/ +docker build -f .devcontainer/Dockerfile -t vrf-devcontainer . +``` + +**Option 2: Runtime CA Installation** +1. Mount CA files from the host +2. The post-create script installs them automatically + +#### Proxy Build Args + +For HTTP/HTTPS proxy environments: + +```bash +docker build --no-cache \ + --build-arg NODE_VERSION=20 \ + --build-arg HTTP_PROXY="http://proxy.company:8080" \ + --build-arg HTTPS_PROXY="http://proxy.company:8080" \ + -f .devcontainer/Dockerfile -t vrf-devcontainer . +``` + +## Troubleshooting + +### Tests failing with "vscode not found" +Ensure tests are run with `NODE_PATH=./test/helpers` so the vscode stub is resolved. + +### Fake timers not working +If using sinon fake timers, ensure they're properly restored in test teardown to avoid affecting other tests. + +### TypeScript compilation errors +Run `npm install` to ensure all type definitions are installed, including `@types/vscode`, `@types/node`, and `@types/mocha`. + +## Contribution Guidelines + +### Code Style + +- Follow TypeScript best practices +- Use strict type checking (already enabled in `tsconfig.json`) +- Add JSDoc comments for public APIs +- Keep functions focused and single-purpose +- Use descriptive variable and function names + +### Pull Request Process + +1. Fork the repository +2. Create a feature branch (`git checkout -b feature/amazing-feature`) +3. Make your changes +4. Add/update tests as needed +5. Ensure all tests pass (`npm run test:unit`) +6. Ensure code compiles (`npm run compile`) +7. Run the linter (`npm run lint`) +8. Commit your changes with clear messages +9. Push to your fork +10. Open a Pull Request + +### Commit Messages + +Use clear, descriptive commit messages: +- `feat: add support for remote workspaces` +- `fix: handle permission errors during restoration` +- `test: add coverage for edge cases in file-restorer` +- `docs: update README with new features` + +## Testing Your Changes + +Before submitting a PR: + +1. **Unit Tests**: Ensure all tests pass + ```bash + npm run test:unit + ``` + +2. **Integration Testing**: Test in a real VS Code instance + - Press `F5` to launch Extension Development Host + - Create/delete files and test restoration + - Verify edge cases (permissions, nested folders, etc.) + +3. **Cross-platform**: If possible, test on multiple OSes + +## Getting Help + +- Check existing [Issues](https://github.com/minouris/vscode-restore-folder/issues) +- Review [Pull Requests](https://github.com/minouris/vscode-restore-folder/pulls) +- Ask questions in new issues with the "question" label + +## License + +By contributing, you agree that your contributions will be licensed under the MIT License. + +--- + +Thank you for contributing to Local History Restore! diff --git a/README.md b/README.md index d3f2391..921b67e 100644 --- a/README.md +++ b/README.md @@ -1,251 +1,123 @@ -# VS Code Restore Folder +# Local History Restore -A small VS Code extension that discovers deleted files and folders from VS Code local history and allows restoring them into the workspace. +Recover deleted files and folders from VS Code's local history with just a few clicks. Never lose your work again! -This repository contains the extension source (TypeScript), focused unit tests (Mocha + Chai + Sinon), and test helpers to run the extension code under Node for fast unit testing. +## ✨ Features -## What's in the repo -- `src/` - TypeScript source files for the extension -- `src/test/` - Unit tests (Mocha + ts-node) with focused coverage across modules -- `test/helpers/vscode/` - Minimal `vscode` runtime stub used by tests (loaded via NODE_PATH) -- `package.json` - scripts and devDependencies used for build/test/package +- **🔍 Auto-Discovery**: Automatically scans VS Code's local history to find your deleted files and folders +- **📁 Tree View Integration**: Browse deleted items in a convenient tree view right in the Explorer sidebar +- **⚡ Quick Restore**: Restore individual files, entire folders, or multiple selections with a single click +- **🔄 Real-Time Updates**: Automatically detects when files are deleted and updates the view +- **📊 Hierarchical Display**: Organizes deleted items by their original folder structure for easy navigation +- **💾 Smart Recovery**: Always restores the most recent version before deletion -## Development +## 🚀 Getting Started -Prerequisites: Node.js (16+ recommended), npm. +### Installation -Install dependencies: +1. Open VS Code +2. Go to the Extensions view (`Ctrl+Shift+X` / `Cmd+Shift+X`) +3. Search for "Local History Restore" +4. Click Install -```bash -npm install -``` +### How to Use -Build (TypeScript compile): +#### View Deleted Items -```bash -npm run compile -``` +The "Deleted Items" view appears automatically in the Explorer sidebar when you open a workspace. If you don't see it: -Note: TypeScript compilation is used for packaging. Unit tests run via ts-node and do not require a full `npm run compile` step during development. +1. Open the Explorer sidebar (`Ctrl+Shift+E` / `Cmd+Shift+E`) +2. Look for the "Deleted Items" section +3. Click the refresh button to scan for deleted files -## Running unit tests +#### Restore Files and Folders -Tests are written in TypeScript and run under Mocha + ts-node. The test runner uses a small `vscode` stub located in `test/helpers/vscode` so tests run in plain Node. +**Single Item:** +- Click the restore icon (➕) next to any deleted file or folder in the tree view -Run unit tests: +**Multiple Items:** +1. Select multiple items using `Ctrl+Click` / `Cmd+Click` +2. Right-click and choose "Restore Selected Items" -```bash -# use NODE_PATH so `require('vscode')` resolves to the test helper -NODE_PATH=./test/helpers mocha -r ts-node/register 'src/test/**/*.ts' --exit -``` +**From Command Palette:** +1. Open Command Palette (`Ctrl+Shift+P` / `Cmd+Shift+P`) +2. Type "Local History Restore: Refresh" to scan for deleted items +3. Use the tree view to restore items -Run coverage (c8): +## 📋 Requirements -```bash -NODE_PATH=./test/helpers c8 mocha -r ts-node/register 'src/test/**/*.ts' -``` +- **VS Code**: Version 1.105.0 or higher +- **Workspace**: Must have at least one workspace folder open +- **File History**: Only works with files that were previously opened and edited in VS Code -Notes: -- Tests avoid touching your real filesystem when possible by using `mock-fs` or stubbing `FileSystemUtils`. -- Some tests set up fake workspace folders by assigning `vscode.workspace.workspaceFolders` to test values. +## 💡 How It Works -## Project structure & key modules +VS Code automatically creates backup copies of files as you edit them. This extension: -- `backup-scanner.ts` — discovers entries in VS Code local history and creates `DeletedItem` records. -- `deleted-items-provider.ts` — `TreeDataProvider` that exposes deleted items to the Explorer view. -- `item-organizer.ts` — organizes flat lists into a hierarchical tree. -- `file-restorer.ts` — logic to restore single files, empty directories, and recursively restore folders. -- `file-watcher-manager.ts` — creates `FileSystemWatcher` objects and performs debounced refreshes. -- `file-system-utils.ts` — small helpers wrapping fs operations and URI normalization. +1. Scans VS Code's local history directory for backup files +2. Identifies which files have been deleted from your workspace +3. Displays them in an organized tree view +4. Allows you to restore them with their most recent content -## Packaging the extension (how to create a .vsix) +**Note**: The extension can only recover files that VS Code has backed up. Files that were never opened in VS Code or were deleted before being saved cannot be recovered. -High-level steps to create a VSIX for the extension: +## ⚠️ Known Limitations -1. Ensure `package.json` has the correct `name`, `version`, `publisher`, `engines.vscode` and `activationEvents` fields. -2. Build/compile the TypeScript sources: +- Only files that were opened and edited in VS Code can be restored (files with backup history) +- Files deleted outside of VS Code that were never opened cannot be recovered +- Backup locations vary by operating system and VS Code installation +- Local history may be cleared by VS Code based on its internal retention policies -```bash -npm run compile -``` - -3. Install `vsce` if you don't have it (globally or use npx): - -```bash -npx vsce package -``` - -This will produce a `.vsix` file which can be installed locally or published. - -Publishing to the Marketplace requires a publisher account and credentials; see `vsce` docs for details. - -Helpful packaging notes -- Make sure `out/extension.js` (the compiled extension entry) is listed in your `files`/`package.json` if you restrict published files. -- Prefer using `npx vsce package` (no global install required). -- If you want CI-based publishing, create a GitHub Action that runs `npm ci`, `npm run compile`, and `npx vsce publish --pat $VSCE_PAT` with a Personal Access Token stored in secrets. - -## Troubleshooting tests -- If tests fail under Node complaining about `vscode` not found, ensure you run tests with the `NODE_PATH=./test/helpers` prefix so the `vscode` stub is resolved. -- If a test uses fake timers (sinon), ensure timers are restored in the test tear-down to avoid affecting other tests. - -## Next steps and packaging help -If you'd like, I can: - -- Prepare a small `package.json` packaging script (e.g. `npm run package` that runs `npm run compile && npx vsce package`). -- Add a CI workflow for building and optionally publishing the extension. -- Run a final audit to ensure the `package.json` extension manifest fields (publisher, name, displayName, repository, engines.vscode) are present and valid. - -## Devcontainer: corporate TLS, CA certs and proxy build args - -If you're developing behind a corporate TLS-intercepting proxy (for example Zscaler) you'll need to ensure the devcontainer build and npm can validate your company's CA. Two options are supported in this repository: - -- Provide CA files in the repo build context under `.devcontainer/certs/` (the Dockerfile will copy and install these at build time). -- Or mount host CA files into the container at runtime and run the post-create script which installs them into the container trust store. - -Build-time notes (current Dockerfile behavior) -- The Dockerfile copies any files found in `.devcontainer/certs/` into `/usr/local/share/ca-certificates/`, ensures they have a `.crt` extension, concatenates them into `/usr/local/share/ca-certificates/combined-ca.crt`, runs `update-ca-certificates`, and sets the following environment variables so Node/npm use the combined CA bundle during build-time installs: - - - `NODE_EXTRA_CA_CERTS=/usr/local/share/ca-certificates/combined-ca.crt` - - `NPM_CONFIG_CAFILE=/usr/local/share/ca-certificates/combined-ca.crt` - -Example: add your corporate root CA(s) to the repo (or symlink them) as PEM/CRT files: - -```bash -mkdir -p .devcontainer/certs -cp /path/to/your-corporate-root-ca.pem .devcontainer/certs/Zscaler_Root_CA.pem -``` - -Then build the devcontainer image (mirrors what VS Code Remote - Containers does): - -```bash -docker build --no-cache -f .devcontainer/Dockerfile -t vrf-devcontainer:debug --build-arg NODE_VERSION=20 /path/to/repo -``` - -Proxy build args -- If your environment requires an HTTP/HTTPS proxy to reach the registry, pass `HTTP_PROXY` and `HTTPS_PROXY` as build args. The Dockerfile forwards them into the image environment, for example: - -```bash -docker build --no-cache \ - --build-arg NODE_VERSION=20 \ - --build-arg HTTP_PROXY="http://proxy.company:8080" \ - --build-arg HTTPS_PROXY="http://proxy.company:8080" \ - -f .devcontainer/Dockerfile -t vrf-devcontainer:debug /path/to/repo -``` - -Runtime (post-create) alternative -- If you prefer not to include corporate certs in the image build context, you can mount them from the host into the container at runtime and let the `.devcontainer/post-create.sh` script install them and then run any npm installations (the script already looks for common paths and installs certs). - -Which approach to use? -- Build-time install (default in this repo): ensures `npm install -g vsce` and other global installs succeed during the image build. Use this when you want a self-contained image that can run without host mounts. -- Post-create (runtime) install: safer when you don't want secrets or corporate certs in the image build context. To prefer this, remove the global `vsce` install from the Dockerfile and add it to `post-create.sh` — the repo already contains a post-create script that installs certs and runs `npm install` for project dependencies. - -If you'd like, I can switch to the runtime approach for you (moves global `vsce` install into `post-create.sh`) — it avoids placing private certs into the image but does require a successful mount or host-provided certs at runtime. - -Tell me which of these you'd like to do next and I'll implement it. - ---- -README last updated: automated by test/coverage iteration -# Local History Restore - VS Code Extension - -A VS Code extension that helps you restore deleted files and folders from VS Code's local history. Never lose your work again! - -## Features - -- **List Deleted Items**: Scan your workspace to find files and folders that have been deleted but still exist in VS Code's local history -- **Multi-Select Restoration**: Select multiple items for batch restoration -- **Recursive Restoration**: Automatically restore entire folder structures -- **Most Recent Version**: Always restores the most recent version before deletion -- **Explorer Integration**: Convenient tree view in the Explorer sidebar - -## Usage - -### 1. List Deleted Files and Folders - -- Open the Command Palette (`Ctrl+Shift+P` / `Cmd+Shift+P`) -- Run the command: `Local History Restore: List Deleted Files and Folders` -- The extension will scan your workspace and display deleted items in the Explorer sidebar - -### 2. Restore Items - -**Option A: From the Tree View** -1. Navigate to the "Deleted Items" view in the Explorer sidebar -2. Click the restore icon (📁) next to any item to restore it individually -3. Or select multiple items and use the context menu - -**Option B: Using Commands** -1. After listing deleted items, use `Local History Restore: Restore Selected Items` -2. Confirm the restoration when prompted - -## How It Works - -The extension scans VS Code's local history and backup files to identify: -- Files that existed in your workspace but have been deleted -- The most recent backup versions of those files -- Folder structures that can be restored recursively - -VS Code automatically creates backup files when you edit documents, and this extension leverages those backups to restore your deleted work. - -## Requirements - -- VS Code 1.105.0 or higher -- A workspace with files (the extension only works within workspaces) - -## Limitations - -- Can only restore files that were opened and edited in VS Code (and thus have backup files) -- Cannot restore files that were deleted outside of VS Code without being opened first -- Backup file locations may vary by operating system and VS Code installation - -## Extension Commands +## 🎯 Extension Commands This extension contributes the following commands: -- `minouris-local-history-restore.listDeleted`: List Deleted Files and Folders -- `minouris-local-history-restore.restoreSelected`: Restore Selected Items -- `minouris-local-history-restore.restoreItem`: Restore Individual Item - -## Development +| Command | Description | +|---------|-------------| +| `Local History Restore: Refresh` | Manually refresh the list of deleted items | +| `Restore Item` | Restore a single file (available in tree view context menu) | +| `Restore Folder` | Restore an entire folder with all its contents | -To run this extension in development mode: +## 🆘 Troubleshooting -1. Clone this repository -2. Install dependencies: `npm install` -3. Compile the TypeScript: `npm run compile` -4. Press `F5` to open a new Extension Development Host window -5. Test the extension in the new window +**No deleted items showing up?** +- Ensure you have a workspace folder open +- Click the refresh button in the "Deleted Items" view +- Verify that VS Code has created backups (check if files were edited in VS Code before deletion) -### Building +**Restore not working?** +- Check that you have write permissions in the target directory +- Ensure the file path is not too long for your operating system +- Try refreshing the view and attempting the restore again -```bash -npm run compile -``` +## 📝 Release Notes -### Running Tests +See the [CHANGELOG](CHANGELOG.md) for detailed release information. -```bash -npm test -``` +### Version 1.0.0 -## Release Notes +- Initial release +- Automatic detection of deleted files and folders +- Tree view integration in Explorer sidebar +- Single and multi-item restoration +- Real-time file system monitoring +- Hierarchical folder organization -### 0.0.1 +## 🤝 Contributing -- Initial release -- Basic functionality to list and restore deleted files and folders -- Explorer tree view integration -- Multi-select restoration support +Found a bug or have a feature request? Please visit our [GitHub repository](https://github.com/minouris/vscode-restore-folder) to: -## Contributing +- Report issues +- Suggest new features +- Submit pull requests +- View the source code -This extension is open source. Feel free to contribute by: -- Reporting bugs -- Suggesting new features -- Submitting pull requests +For developers interested in contributing, see the [CONTRIBUTING.md](CONTRIBUTING.md) guide in our repository. -## License +## 📄 License -[MIT License](LICENSE) +This extension is licensed under the [MIT License](LICENSE). --- -**Note**: This extension works by scanning VS Code's internal backup and history files. The availability of deleted files depends on VS Code's backup mechanisms and may vary based on your settings and usage patterns. +**Enjoy using Local History Restore?** Please consider leaving a rating and review! Your feedback helps improve the extension.