Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
e803063
Skyline: Convert WebClient use to HttpClient
Oct 10, 2025
cd95521
- More conversions of WebClient to HttpClient
Oct 11, 2025
caba79d
- Added the ToolStoreDlg and worked through a lot of consistency issues
Oct 13, 2025
7c578bb
Merge remote-tracking branch 'remotes/origin/master' into Skyline/wor…
Oct 13, 2025
ffc06aa
- revert OperationCanceledException handling in LongWaitDlg (per Nick…
Oct 13, 2025
ca68d42
- fix HttpClientWithProgress support for accessing LongWaitDlg.Cancel…
Oct 14, 2025
8917378
- add more testing of HttpClientWithProgress integration with LongWai…
Oct 15, 2025
eb30422
Merge branch 'master' into Skyline/work/20251010_webclient_replacement
brendanx67 Oct 15, 2025
76bc093
- more tests in HttpClientWithProgressIntegrationTest for fairly comp…
Oct 15, 2025
fdc966c
- fix code inspection error in HttpClientWithProgressIntegrationTest
Oct 15, 2025
8f19d9e
Merge branch 'master' into Skyline/work/20251010_webclient_replacement
brendanx67 Oct 16, 2025
4f71087
- updated .md files for LLM-assisted development
Oct 16, 2025
c381431
- Get 5 tests testing network failure and cancellation during downloa…
Oct 18, 2025
252bdc3
Merge remote-tracking branch 'remotes/origin/master' into Skyline/wor…
Oct 18, 2025
dbcf6bf
- clean up ToolUpdatesTest
Oct 19, 2025
e63173d
- fix cancellation when cancel button is clicked during a read operat…
Oct 19, 2025
5ac83b4
- clean up use of HttpClientWithProgress strings for testing to local…
Oct 19, 2025
849aadb
Merge branch 'master' into Skyline/work/20251010_webclient_replacement
brendanx67 Oct 19, 2025
4e8a305
Implement TODO directory structure with active/completed/backlog/arch…
Oct 19, 2025
a5ca814
Add PowerShell developer utilities to scripts/misc
Oct 19, 2025
15fa82d
Merge branch 'Skyline/work/20251010_webclient_replacement' of github.…
Oct 19, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 9 additions & 28 deletions .cursorrules
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# This file provides Cursor-specific behavior guidance.
# For detailed coding conventions, style guidelines, and testing patterns,
# see STYLEGUIDE.md - the comprehensive style guide used by all AI tools.
# For project context, common gotchas, and architectural patterns,
# see MEMORY.md - essential context for AI tools working on this project.

[project]
name = "ProteoWizard (pwiz)"
Expand Down Expand Up @@ -38,6 +40,7 @@ entry_points = [
- When adding sources, update the appropriate Jamfile or Visual Studio project.
- Use existing vendor libraries from `libraries/`; do not fetch replacements.
- For documentation, add concise notes to `README.md` and `doc/`.
- Project conventions: See MEMORY.md for essential project context and common gotchas.

[skyline]
primary_solution = "pwiz_tools/Skyline/Skyline.sln"
Expand All @@ -55,6 +58,10 @@ docs = [
- Use fenced code blocks only for relevant snippets or commands.
- Default to read-only discovery before edits; then apply focused edits.

[async_patterns]
# See STYLEGUIDE.md for comprehensive async/await guidelines
reference = "STYLEGUIDE.md"

[build_and_testing]
- LLM agents CANNOT build or run this project directly.
- Build and test operations must be performed by the developer using Visual Studio.
Expand All @@ -63,34 +70,8 @@ docs = [
- Do not attempt to run tests or execute the application.

[file_headers]
standard_header = """
/*
* Original author: [Author Name] <[email] .at. [domain]>,
* [Affiliation]
* AI assistance: Cursor (Claude Sonnet 4) <cursor .at. anysphere.co>
*
* Copyright [Year] University of Washington - Seattle, WA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
"""
ai_attribution = {
required = "Always include AI assistance line when code is created or significantly modified with AI tools"
format = "Cursor ([model names]) <cursor .at. anysphere.co>"
position = "After original author, before copyright"
email_format = "Use .at. format to avoid spam harvesting"
multiple_models = "List all models used if multiple AI systems contributed significantly"
}
# See STYLEGUIDE.md for file header format and AI attribution guidelines
reference = "STYLEGUIDE.md"

[testing]
# See STYLEGUIDE.md for comprehensive testing guidelines
Expand Down
259 changes: 259 additions & 0 deletions MEMORY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
# Skyline Project Memory & Context

This document provides essential context for AI tools working on the Skyline project, including architectural patterns, common gotchas, and project scale information.

## Project Scale & Context

### Codebase Size
- **~900,000 lines of code** across multiple languages (C#, C++, JavaScript, etc.)
- **17+ years of evolution** - long-term maintenance is critical
- **8 active developers** working concurrently
- **100+ hours daily** of automated testing across multiple platforms

### Development Environment
- **Primary platform**: Windows with Visual Studio
- **Build system**: Boost.Build with MSVC/GCC support
- **Version control**: Git with GitHub
- **Testing**: Comprehensive automated test suite (unit, functional, performance)
- **Localization**: English, Chinese (Simplified), Japanese

## Common Gotchas

### Threading Guidelines
- **UI thread only** for WinForms operations
- Use `Control.Invoke()` to marshal operations back to UI thread
- Background operations use `ActionUtil.RunAsync()` (NOT async/await keywords)
- Never access UI controls from background threads

### Asynchronous Programming Patterns

#### CRITICAL: No async/await keywords
- **DO NOT use `async`/`await` keywords** in C# code
- Use `ActionUtil.RunAsync()` for background operations in Skyline code
- Use `CommonActionUtil.RunAsync()` only in Common/CommonUtil libraries (no Skyline dependencies)

#### Choosing the right RunAsync
**In Skyline code (`pwiz_tools/Skyline/`):**
- **Use `ActionUtil.RunAsync()`** from `pwiz.Skyline.Util.Extensions`
- Provides proper localization/translation support for resource strings
- Required for code that accesses RESX files during background operations
- Add `using pwiz.Skyline.Util.Extensions;`

**In Common libraries (`pwiz_tools/Shared/`):**
- **Use `CommonActionUtil.RunAsync()`** from `pwiz.Common.SystemUtil`
- For libraries that must not depend on Skyline-specific code
- Does not provide Skyline localization support

### CRITICAL: .resx file workflow
When adding new resource strings to a .resx file, you MUST also add the corresponding public static string properties to the .Designer.cs file. The compiler will fail with CS0117 errors if the Designer.cs file is not updated.

Example workflow:
1. Add `<data name="MyNewString" xml:space="preserve"><value>My New String</value></data>` to .resx
2. Add `public static string MyNewString => ResourceManager.GetString("MyNewString", resourceCulture);` to .Designer.cs
3. Ensure properties are added in alphabetical order
4. Build to verify no CS0117 errors

### Translation-Proof Testing
**NEVER use English text literals in test assertions** - all UI text is localized to Chinese and Japanese, so English-only assertions will break.

**Bad (will break in localized builds):**
```csharp
// ❌ This will fail when UI is in Chinese or Japanese
StringAssert.Contains(messageDlg.Message, "connection");
Assert.IsTrue(errorDlg.Message.Contains("not found"));
```

**Good (translation-proof):**
```csharp
// ✅ Reconstruct expected message from resource strings
var expectedMessage = string.Format(
MessageResources.HttpClientWithProgress_MapHttpException_Failed_to_connect_to__0___Please_check_your_network_connection__VPN_proxy__or_firewall_,
"cran.r-project.org");
Assert.AreEqual(expectedMessage, messageDlg.Message);
```

### DRY (Don't Repeat Yourself) - Critical for Long-Term Maintenance
**Skyline has been maintained for over 17 years.** Repetitive code becomes a maintenance nightmare in long-lived projects. We strongly enforce DRY principles.

**Why DRY Matters in Skyline**
- **17+ years of evolution** - Code changes frequently, and repetitive patterns multiply maintenance burden
- **Large codebase** - Duplication compounds across thousands of files
- **Multiple developers** - Inconsistent patterns make code harder to understand and modify
- **Bug fixes** - Must be applied in multiple places, increasing risk of missed locations

**DRY Violations to Avoid**

❌ **Bad - Repetitive Setup Code:**
```csharp
// Test 1
private static void TestDownloadSuccess()
{
var packages = new Collection<ToolPackage>();
var installer = ShowDialog<RInstaller>(() => InstallProgram(PPC, packages, false));
WaitForConditionUI(10 * 1000, () => installer.IsLoaded);
RunUI(() => installer.TestRunProcess = new TestRunProcess { ExitCode = 0 });
// ... test logic
}

// Test 2 - DUPLICATED SETUP
private static void TestDownloadFailure()
{
var packages = new Collection<ToolPackage>();
var installer = ShowDialog<RInstaller>(() => InstallProgram(PPC, packages, false));
WaitForConditionUI(10 * 1000, () => installer.IsLoaded);
RunUI(() => installer.TestRunProcess = new TestRunProcess { ExitCode = 1 });
// ... test logic
}
```

✅ **Good - DRY with Helper:**
```csharp
// Helper method eliminates duplication
private static RInstaller FormatRInstaller(int installExitCode)
{
var packages = new Collection<ToolPackage>();
var installer = ShowDialog<RInstaller>(() => InstallProgram(PPC, packages, false));
WaitForConditionUI(10 * 1000, () => installer.IsLoaded);
RunUI(() => installer.TestRunProcess = new TestRunProcess { ExitCode = installExitCode });
return installer;
}

// Tests focus on behavior, not setup
private static void TestDownloadSuccess()
{
var installer = FormatRInstaller(installExitCode: 0);
// ... test logic
}

private static void TestDownloadFailure()
{
var installer = FormatRInstaller(installExitCode: 1);
// ... test logic
}
```

**DRY Patterns in Skyline**

1. **Test Setup Helpers**
- Extract common dialog setup into helper methods
- Use parameters to customize behavior (exit codes, connection states, etc.)
- Place helpers after the tests that use them

2. **Resource String Reconstruction**
- Reconstruct expected messages from resource strings instead of hardcoding
- Use `string.Format()` with the same resource strings as production code
- Ensures tests work in all languages (English, Chinese, Japanese)

3. **Common UI Patterns**
- Extract repeated UI interaction patterns
- Use consistent naming for similar operations across different dialogs
- Create reusable validation methods

4. **Exception Handling**
- Use centralized exception mapping (`MapHttpException`, `IsProgrammingDefect`)
- Avoid duplicating exception classification logic
- Standardize error message construction

**When to Extract Helpers**

Extract when you see:
- 3+ lines of identical code across multiple methods
- Similar patterns with only parameter differences
- Repeated resource string lookups or formatting
- Duplicated validation logic
- Common UI interaction sequences

Don't extract:
- Single-use code (unless it's clearly a future pattern)
- Trivial one-liners
- Code that's only similar but not identical

**Maintenance Benefits**

Before DRY:
- Change requires editing 8 places
- Risk of missing locations
- Inconsistent behavior across similar scenarios
- Harder to understand overall patterns

After DRY:
- Change requires editing 1 place
- Impossible to miss locations
- Consistent behavior guaranteed
- Clear, focused test logic

**Remember:** In a 17-year-old project, every line of duplicated code is a future maintenance burden. Be ruthless about eliminating repetition.

### Exception Handling Patterns
- Use centralized exception mapping (`MapHttpException`, `IsProgrammingDefect`)
- Avoid duplicating exception classification logic
- Standardize error message construction
- Use `UserMessageException` base class for user-facing exceptions
- Distinguish between programming errors (re-thrown) and user-actionable errors (displayed)

### File and Member Ordering
Order members to make high-level logic easy to read first:
1. static variables/fields
2. static public interface methods
3. private instance fields
4. constructor(s)
5. public interface (instance) methods and properties
6. private helper methods

Place private helpers after the public methods that use them; keep helpers close to their primary call sites.

### Build System
- **Use `quickbuild.bat` on Windows** - do not introduce new build systems
- **Respect existing indentation** - avoid unrelated reformatting
- **Keep code style intact** - do not reformat unrelated files; preserve tabs/spaces
- **Update appropriate Jamfile or Visual Studio project** when adding sources
- **Use existing vendor libraries** from `libraries/`; do not fetch replacements

## Project Structure

### Key Directories
- `pwiz/` - Core C++ libraries and tools
- `pwiz_tools/Skyline/` - Main Skyline application (C#)
- `pwiz_tools/Shared/` - Shared utilities and common code
- `libraries/` - Third-party dependencies
- `build-nt-x86/msvc-release-x86_64/` - Build outputs

### Entry Points
- `quickbuild.bat` - Main build script
- `pwiz.sln` - Visual Studio solution
- `pwiz_tools/Skyline/Skyline.sln` - Skyline-specific solution
- `doc/index.html` - Documentation

### Testing
- **Unit tests**: `Test` and `TestData` projects (fast, no UI)
- **Functional tests**: `TestFunctional`, `TestPerf`, `TestTutorial` projects (UI required)
- **Performance tests**: Large datasets, run less frequently
- **Tutorial tests**: Automated implementation of documentation tutorials

## LLM-Specific Guidelines

### Context Management
- Always read `TODO-YYYYMMDD.md` for current branch context
- Update TODO file with every commit
- Remove TODO file before merging to master
- Follow branch naming conventions: `Skyline/work/YYYYMMDD_description`

### Code Quality
- Match surrounding file style exactly
- Prefer focused edits over broad refactoring
- Keep methods small and cohesive
- Extract helpers when duplication exceeds 3 lines
- Use descriptive, intention-revealing names

### Testing Requirements
- All new code must have appropriate tests
- Use translation-proof assertions
- Follow DRY principles in test code
- Prefer functional tests for UI features
- Use unit tests for pure logic

### Documentation
- Update relevant documentation files
- Add concise notes to `README.md` and `doc/` when needed
- Use XML documentation for public APIs
- Keep comments focused and meaningful
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,13 @@ The project avoids `async`/`await` and .NET Task support in favor of determinist
- **Prefer synchronous operations** on background threads when possible
- **Thread marshaling** - Use `Invoke()` for UI thread operations from background threads

Executables note: Projects under `pwiz_tools/Skyline/Executables` are separate solutions (most build standalone EXEs or developer tools, some ship with Skyline). They are not built by `Skyline.sln`, but should generally follow the same coding conventions unless a local project override is required. See the Tool Store: https://skyline.ms/tools.url
Executables note: Projects under `pwiz_tools/Skyline/Executables` are separate solutions (most build stand-alone EXEs or developer tools, some ship with Skyline). They are not built by `Skyline.sln`, but should generally follow the same coding conventions unless a local project override is required. See the Tool Store: https://skyline.ms/tools.url

EditorConfig: Repository-wide `.editorconfig` enforces core C# naming/formatting so separate solutions (including `pwiz_tools/Skyline/Executables`) inherit consistent style in Visual Studio.

Notes for AI/code assistants (Cursor):

- Prefer invoking `quickbuild.bat` on Windows; avoid adhoc compiler calls
- Prefer invoking `quickbuild.bat` on Windows; avoid ad-hoc compiler calls
- Do not reformat unrelated code; keep original indentation and spacing
- Use existing Jamfiles/solution instead of introducing new build systems
- When adding C++ files, update the appropriate Jamfile or Visual Studio project as needed
Loading