Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
1c2528c
Document UV package manager research findings
webfiltered Aug 26, 2025
6982a24
Add comprehensive UV pip install output analysis
webfiltered Aug 26, 2025
ec3c2a1
Fix UV output analysis after complete file reading
webfiltered Aug 26, 2025
5ae553f
Add specific output examples for each stage transition
webfiltered Aug 26, 2025
9c25d8f
Document exact verbatim output for stage transitions
webfiltered Aug 26, 2025
a574909
Fix UV output documentation accuracy
webfiltered Aug 26, 2025
fc79b91
Remove cache checking as separate stage
webfiltered Aug 26, 2025
e0ca85d
Add rationale for each phase start marker
webfiltered Aug 26, 2025
9eb4c9e
Make time unit patterns flexible in UV parser
webfiltered Aug 26, 2025
a9dfd1d
Remove erroneously re-added cache_checking stage
webfiltered Aug 26, 2025
f1120b6
Add regex patterns for each UV installation phase
webfiltered Aug 26, 2025
a1966ff
Remove 'Regex pattern:' headers from documentation
webfiltered Aug 26, 2025
8444d4e
Document UV download stream analysis
webfiltered Aug 26, 2025
d07cbbf
Fix UV analysis to avoid hard-coded assumptions
webfiltered Aug 26, 2025
4ffdc7e
Remove example-specific download timeline
webfiltered Aug 26, 2025
56ba7e6
Update UV analysis for cached vs download scenarios
webfiltered Aug 26, 2025
137b84f
Standardize conditional stage documentation
webfiltered Aug 26, 2025
ef781e5
Clean up stage documentation consistency
webfiltered Aug 26, 2025
ebfdd60
Use exact raw output lines from logs
webfiltered Aug 26, 2025
2133d7f
Update UV parser to correctly match documented patterns
webfiltered Aug 26, 2025
e8bef61
Remove redundant installation flows section
webfiltered Aug 26, 2025
fef3aff
Fix inconsistent 'Why this marks the phase' formatting
webfiltered Aug 26, 2025
a431c4f
Clean up python test scripts
webfiltered Aug 26, 2025
9e5ee4f
nit
webfiltered Aug 26, 2025
3ccb0da
Design UV parser interfaces and types
webfiltered Aug 26, 2025
8cde917
Remove unnecessary FinalPackage interface
webfiltered Aug 26, 2025
601450e
Fix LogLevel type based on actual UV output
webfiltered Aug 26, 2025
01774dc
Refactor UV parser to stateless architecture
webfiltered Aug 26, 2025
44ea114
Remove deprecated ParseLineResult interface
webfiltered Aug 26, 2025
d99f0b6
Simplify UVParserOptions for stateless design
webfiltered Aug 26, 2025
4d5d745
Clean up interfaces for stateless parser
webfiltered Aug 26, 2025
cd69e8e
Rename FinalPackageListItem to ChangedPackage
webfiltered Aug 26, 2025
56b63b5
Remove calculated fields from parsed output types
webfiltered Aug 26, 2025
1bca7ac
Remove rawLine and lineNumber from ParsedOutput
webfiltered Aug 26, 2025
69260e9
Refactor UV parser to stateless architecture
webfiltered Aug 26, 2025
2c1bf0f
Implement stateless UV output parser
webfiltered Aug 27, 2025
bd81a8a
Add parse-file script for JSON output
webfiltered Aug 27, 2025
c9ff81d
Update HTTP/2 frame parsing to track direction and bytes
webfiltered Aug 27, 2025
1a1de1b
Refactor Http2Frame to discriminated union
webfiltered Aug 27, 2025
769b3a0
Remove unnecessary type assertions
webfiltered Aug 27, 2025
e67598c
Use 'satisfies' instead of 'as const'
webfiltered Aug 27, 2025
1cf6a8c
Remove redundant Http2Frame union type
webfiltered Aug 27, 2025
38f0feb
Fix loose typing in parser
webfiltered Aug 27, 2025
697a7c3
Add UV state management system
webfiltered Aug 27, 2025
c585c06
nit
webfiltered Aug 28, 2025
8729fc2
Remove .js extensions from TypeScript imports
webfiltered Aug 28, 2025
18c1423
Implement UVProcess class to replace node-pty approach
webfiltered Aug 28, 2025
c3bb123
Rename UV parser files to camelCase convention
webfiltered Aug 28, 2025
cc2302b
Remove .js extensions from all imports
webfiltered Aug 28, 2025
2d9012f
Add uvProcessExamples.ts with UV process usage examples
webfiltered Aug 28, 2025
959ec71
Add proper interfaces and JSDoc to UV factory functions
webfiltered Aug 28, 2025
c495009
Fix egregious TypeScript patterns
webfiltered Aug 28, 2025
7aab498
Rename UV-prefixed symbols to PascalCase
webfiltered Aug 28, 2025
2e05be3
Add install stage tracking to app state
webfiltered Aug 29, 2025
cb0b1ab
Add detailed validation stage tracking
webfiltered Aug 29, 2025
f80b928
Fix critical: Add INSTALLING_REQUIREMENTS stage tracking
webfiltered Aug 29, 2025
1617c89
Add startup debug logger utility
webfiltered Aug 31, 2025
0a4d44b
Add debug logging to ComfyServer startup
webfiltered Aug 31, 2025
a7528c8
Add debug logging to VirtualEnvironment
webfiltered Aug 31, 2025
fd27a2b
Add debug logging to ComfyDesktopApp
webfiltered Aug 31, 2025
4a4664d
Add debug logging to DesktopApp main flow
webfiltered Aug 31, 2025
fe1b6cc
Add debug logging to main entry point
webfiltered Aug 31, 2025
e5c6961
Run formatter on debug logging code
webfiltered Aug 31, 2025
1c49fb1
Allow InstallStage to be used in frontend
webfiltered Sep 1, 2025
7c0e762
Add progress values to comfyInstallation.ts validation stages
webfiltered Sep 3, 2025
cbb1772
Add progress value to IDLE stage in appState.ts
webfiltered Sep 3, 2025
26bce7b
Revert "Add startup debug logger utility"
webfiltered Sep 3, 2025
bce2a3d
Remove validation progress update calls
webfiltered Sep 4, 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
109 changes: 109 additions & 0 deletions astral-uv-research-document.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# Astral UV Package Manager - Comprehensive Research Document

## Overview

UV is an extremely fast Python package and project manager written in Rust by Astral (creators of Ruff). It serves as "a single tool to replace pip, pip-tools, pipx, poetry, pyenv, twine, virtualenv, and more."

### Key Characteristics

- **Performance**: 8-10x faster than pip without caching, 80-115x faster with warm cache
- **Language**: Written in Rust for maximum performance, memory safety, and efficient parallel processing
- **Scope**: Drop-in replacement for multiple Python tools (pip, pip-tools, pipx, poetry, pyenv, twine, virtualenv)

## Core Architecture

### PubGrub Algorithm

UV uses the **PubGrub algorithm** (via pubgrub-rs) for dependency resolution:

- **Incremental version solver** using techniques like:
- Unit propagation
- Logical resolution
- Conflict-driven clause learning
- **Forking Resolver**: Can split resolution for different environment markers (inspired by Poetry)

### Key Optimizations

- **Parallel Downloads**: Downloads multiple packages simultaneously
- **Efficient Metadata Handling**: Only downloads metadata files instead of entire wheels for dependency resolution
- **Global Caching**: Uses Copy-on-Write and hardlinks to minimize disk usage
- **Bytecode Compilation**: Optional post-install compilation for faster startup

## Debug Logging System

### Environment Variables

#### RUST_LOG

Controls log verbosity level using tracing_subscriber-compatible filters:

- `RUST_LOG=trace` - Most verbose (trace-level logging)
- `RUST_LOG=debug` - Debug-level logging
- `RUST_LOG=uv=debug` - Debug logging for UV specifically
- `RUST_LOG=warn,uv=debug` - Global warn, UV debug

#### UV_LOG_CONTEXT

- Adds additional context and structure to log messages
- Only effective when logging is enabled (via RUST_LOG or -v)
- Enhances debug output with contextual information

#### Other Debug Variables

- `RUST_BACKTRACE=1` or `RUST_BACKTRACE=full` - Stack traces on errors
- `TRACING_DURATIONS_FILE` - Performance analysis tracing
- `UV_STACK_SIZE` - Sets stack size for UV operations
- `UV_NO_PROGRESS` - Disables progress output
- `UV_OFFLINE` - Disables network access
- `UV_PREVIEW` - Enables preview mode features

## Known Limitations

- **Build Backend Output**: UV doesn't display build logs from native extensions in verbose mode (unlike pip)
- **Sub-command Output**: Limited visibility into subprocess operations

## File System Locations

- **Cache Directory**: `~/.cache/uv/`
- `simple-v16/` - Package index cache
- `wheels-v5/` - Downloaded wheels cache
- `built-wheels-v5/` - Built wheels cache
- **Virtual Environment**: `.venv/` in project directory
- **Configuration**: Platform-specific (macOS: `~/Library/Application Support/`)

## Performance Characteristics

- **Resolution Speed**: Milliseconds for most packages
- **Download Parallelism**: Multiple simultaneous connections
- **Cache Efficiency**: Hardlinks to avoid duplication
- **Memory Usage**: Rust's zero-cost abstractions minimize overhead

## Integration Notes

### For ComfyUI Desktop

- UV is bundled as the primary package manager
- Replaces pip for dependency installation
- Provides faster installation times
- Better error messages and conflict resolution

### Command Examples

```bash
# Basic installation with debug output
UV_LOG_CONTEXT=1 RUST_LOG=debug uv pip install [packages]

# Clean cache
uv cache clean

# Uninstall packages
uv pip uninstall [packages] --quiet
```

## Future Considerations

When parsing UV output:

1. Handle parallel operations (same timestamp, different operations)
2. Parse structured data from debug logs for detailed insights
3. Consider that some operations may be cached and thus instantaneous
9 changes: 9 additions & 0 deletions src/main-process/appState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { EventEmitter } from 'node:events';
import { InstallStage } from '@/constants';
import { AppStartError } from '@/infrastructure/appStartError';
import type { Page } from '@/infrastructure/interfaces';
import { getUvState } from '@/uv-parser/uvState';
import type { IUvState } from '@/uv-parser/uvStateInterfaces';

import { type InstallStageInfo, createInstallStageInfo } from './installStages';

Expand Down Expand Up @@ -31,6 +33,8 @@ export interface IAppState extends Pick<EventEmitter<AppStateEvents>, 'on' | 'on
readonly loaded: boolean;
/** The last page the app loaded from the desktop side. @see {@link AppWindow.loadPage} */
currentPage?: Page;
/** UV process state manager for tracking package installations. */
readonly uvState: IUvState;
/** Current installation stage information. */
readonly installStage: InstallStageInfo;

Expand All @@ -50,12 +54,17 @@ class AppState extends EventEmitter<AppStateEvents> implements IAppState {
ipcRegistered = false;
loaded = false;
currentPage?: Page;
readonly uvState: IUvState;
installStage: InstallStageInfo;

constructor() {
super();
// Initialize install stage to idle
this.installStage = createInstallStageInfo(InstallStage.IDLE, { progress: 0 });
// Initialize UV state
this.uvState = getUvState();
// Initialize install stage to idle
this.installStage = createInstallStageInfo(InstallStage.IDLE, { progress: 0 });
}

initialize() {
Expand Down
58 changes: 58 additions & 0 deletions src/uv-parser/interfaces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* UV Parser Interface Definitions
*
* Stateless interfaces for implementing a UV pip install output parser.
* The parser processes each line independently without maintaining state.
*/
import type { UvParsedOutput } from './types';

/**
* Stateless UV output parser interface.
* Each line is parsed independently without requiring context or state.
*/
export interface IUvParser {
/**
* Parse a single line of UV output without any state context.
* Returns undefined if the line cannot be parsed or is not relevant.
*
* @param line - The line to parse
* @returns Parsed output object or undefined
*/
parseLine(line: string): UvParsedOutput | undefined;

/**
* Parse multiple lines of UV output.
* Each line is parsed independently.
*
* @param lines - Array of lines to parse
* @returns Array of parsed outputs (undefined entries filtered out)
*/
parseLines(lines: string[]): UvParsedOutput[];

/**
* Parse a complete UV output string.
* Splits by newlines and parses each line independently.
*
* @param output - Complete output string
* @returns Array of parsed outputs
*/
parseOutput(output: string): UvParsedOutput[];

/**
* Check if a line can be parsed by this parser.
* Useful for filtering or validation.
*
* @param line - The line to check
* @returns True if the line matches any known pattern
*/
canParse(line: string): boolean;

/**
* Get the type of output a line would produce without fully parsing it.
* Useful for routing or filtering.
*
* @param line - The line to check
* @returns The output type or undefined if not parseable
*/
getLineType(line: string): UvParsedOutput['type'] | undefined;
}
46 changes: 46 additions & 0 deletions src/uv-parser/parseFile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* Parse UV output file line by line and output JSON
*
* Usage:
* npx tsx src/uv-parser/parse-file.ts <file-path>
* or
* node --loader tsx src/uv-parser/parse-file.ts <file-path>
*/
import { readFileSync } from 'node:fs';

import { createUvParser } from './parser';

// Main function to allow proper error handling
function main(): void {
// Get file path from command line arguments
const filePath = process.argv[2];

if (!filePath) {
console.error('Usage: npx tsx parse-file.ts <file-path>');
throw new Error('No file path provided');
}

// Read file content
const content = readFileSync(filePath, 'utf8');
const lines = content.split('\n');

// Create parser instance
const parser = createUvParser();

// Parse each line and output JSON
for (const line of lines) {
const parsed = parser.parseLine(line);
if (parsed) {
console.log(JSON.stringify(parsed));
}
}
}

// Run main function and handle errors
try {
main();
} catch (error) {
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
// eslint-disable-next-line unicorn/no-process-exit
process.exit(1);
}
Loading
Loading