Open
Conversation
Add Lorah AI pair programming setup to manage the refactoring of lnk to a stow-like flag-based interface. Includes specification, task tracking, progress logs, and session prompts for initialization and implementation phases.
Create comprehensive task breakdown for stow-like CLI refactor with 24 testable requirements across 4 implementation phases: - Phase 1: Config file support (.lnkconfig, .lnkignore) - Phase 2: Options-based API (package-centric linking) - Phase 3: CLI rewrite (flag-based interface) - Phase 4: Internal function updates Document initial codebase inventory and refactoring plan summary.
Implement Phase 1 of CLI refactor - stow-like config file format: - Add .lnkconfig file discovery and parsing (CLI flags format) - Add .lnkignore file parsing (gitignore syntax) - Implement config discovery precedence chain - Add FlagConfig struct for new config format Discovery order: .lnkconfig in source dir → XDG config → ~/.lnkconfig Tasks completed: LoadConfig for .lnkconfig format, Parse .lnkignore file
Add MergedConfig struct and MergeFlagConfig() function to merge configuration from multiple sources with proper precedence: - Target: CLI flag > .lnkconfig > default (~) - Ignore patterns: Combined from all sources (built-in, config, .lnkignore, CLI) to allow maximum flexibility Extract getBuiltInIgnorePatterns() for reusability and add .lnkconfig and .lnkignore to built-in ignore patterns. Add comprehensive tests covering all merging scenarios including precedence verification, subdirectories, and combined sources. Completes Phase 1 (Config file support) of the CLI refactor.
Add LinkOptions struct to support the new package-based linking interface. This struct replaces the config-based API with fields for SourceDir, TargetDir, Packages, IgnorePatterns, and DryRun. Part of Phase 2 of the CLI refactor to support stow-like usage.
Add CreateLinksWithOptions function that handles package-based linking using LinkOptions struct. Includes helper collectPlannedLinksWithPatterns that uses ignore patterns directly instead of Config objects. Features: - Supports multiple packages in single operation - Handles package "." for flat repository structure - Handles nested package paths (e.g., "private/home") - Skips non-existent packages gracefully - Follows same 3-phase execution as CreateLinks Includes comprehensive unit tests covering single/multiple packages, ignore patterns, dry-run mode, and error cases.
Add RemoveLinksWithOptions function that removes symlinks for specific packages, supporting the new stow-like interface. Includes helper function findManagedLinksForPackages for filtering managed links by package source. - Add findManagedLinksForPackages to find symlinks pointing to specific packages - Implement RemoveLinksWithOptions with package-based filtering - Support multiple packages, dry-run mode, and "." for flat repos - Add createTestSymlink helper for test utilities - Add comprehensive unit tests (8 test cases)
Add StatusWithOptions function that displays symlink status for specific packages instead of using config-based mappings. Reuses existing display logic and findManagedLinksForPackages helper for consistency. Features: - Shows status for only specified packages - Supports multiple packages in single operation - Separates active and broken links - Supports JSON output format - Comprehensive unit tests with 8 test cases
Add PruneWithOptions function to remove broken symlinks using the new package-based API. Unlike the old PruneLinks function, this supports: - Optional packages (defaults to "." if none specified) - Multiple package targeting in a single operation - DryRun flag without confirmation prompts (consistent with other *WithOptions functions) Includes comprehensive unit tests covering edge cases like partial pruning, mixed active/broken links, and graceful handling of no broken links.
Update collectPlannedLinks to accept ignorePatterns directly instead of requiring Config and LinkMapping objects. This simplifies the function signature and aligns it with the new package-based API pattern used by collectPlannedLinksWithPatterns. Changes: - Update collectPlannedLinks signature to take ignorePatterns []string - Replace shouldIgnoreEntry call with direct MatchesPattern usage - Remove unused shouldIgnoreEntry helper function - Update CreateLinks call site to pass config.IgnorePatterns This refactoring maintains backward compatibility with the old config-based CreateLinks API while preparing for the new flag-based CLI.
…sed link discovery Add FindManagedLinksForSources function that finds symlinks pointing to specified source directories without requiring a Config object. This completes the package-based API for Phase 2 of the CLI refactor. The function walks a target directory, identifies symlinks that point to any of the provided source paths, and returns ManagedLink structs with broken link detection. Added comprehensive unit tests covering: - Single and multiple source directories - Broken link detection - System directory skipping - Relative and nested package paths - Empty sources handling
Replace subcommand-based routing (lnk create, lnk status) with stow-like flag-based interface (lnk -C, lnk -S, lnk home). Action flags (mutually exclusive): - -C/--create (default), -R/--remove, -S/--status, -P/--prune - -A/--adopt, -O/--orphan (placeholders for Phase 4) Directory flags: - -s/--source DIR (default: .) - -t/--target DIR (default: ~) Other flags: - --ignore PATTERN (repeatable) - -n/--dry-run, -v/--verbose, -q/--quiet - --no-color, -V/--version, -h/--help Packages are now positional arguments (at least one required for link operations). Examples: - lnk . (flat repo) - lnk home (nested repo) - lnk home private/home (multiple packages) Integrates with .lnkconfig and .lnkignore config files via MergeFlagConfig(). All *WithOptions functions now wired up to CLI action dispatch. BREAKING CHANGE: Removes subcommand interface. Old commands like 'lnk create' must now use 'lnk home' or 'lnk -C home'. Config files are now optional (CLI flags sufficient).
Add new package-based adopt functionality for the flag-based CLI interface: - AdoptOptions struct for passing adopt parameters - AdoptWithOptions function supporting multiple file adoption - CLI integration with -A/--adopt flag + package + file paths - Comprehensive unit tests (9 test cases) Usage: lnk -A <package> <file1> [file2...] [-s source] [-t target] [-n] Example: lnk -A home ~/.bashrc ~/.vimrc The new interface eliminates the need for config files and makes adoption more intuitive by explicitly specifying the package destination and files to adopt.
Add new options-based API for orphaning files from repository management, supporting the new flag-based CLI interface. This completes Phase 4 of the CLI refactor. Changes: - Add OrphanOptions struct with SourceDir, TargetDir, Paths, and DryRun - Implement OrphanWithOptions() function supporting multiple paths - Support orphaning directories (finds all managed links within) - Graceful error handling (continues on failures) - Add comprehensive unit tests (9 test cases) - Update CLI to use OrphanWithOptions for --orphan flag - Update help text to remove "not yet implemented" note
Updated all e2e tests to use the new flag-based CLI syntax: - Changed from subcommands (lnk create) to action flags (lnk -C home) - Updated test assertions to match new command syntax and output - Adapted tests for macOS sandbox constraints that block dotfile creation - Fixed setupTestEnv to skip re-creating existing test files All e2e tests now pass with the new CLI interface. Tests verify: - Action flags: -C/--create, -R/--remove, -S/--status, -P/--prune, -A/--adopt, -O/--orphan - Directory flags: -s/--source, -t/--target - Package arguments and multiple package support - Error handling and edge cases Files modified: - e2e/e2e_test.go - Core command tests - e2e/workflows_test.go - Workflow and integration tests - e2e/helpers_test.go - Test setup helper - .lorah/tasks.json - Mark Task 23 as complete - .lorah/progress.md - Document session progress
Ran all 12 verification examples from spec.md to validate the new flag-based CLI interface. All examples work correctly: - Flat repo linking (lnk .) - Nested package operations (lnk home, lnk home private/home) - Explicit source/target flags - All action flags (-C, -R, -S, -P, -A, -O) - Config file integration (.lnkconfig and .lnkignore) - Adopt and orphan operations All 24 tasks are now complete: - Phase 1: Config file support (3 tasks) - Phase 2: Options-based API (7 tasks) - Phase 3: CLI rewrite (6 tasks) - Phase 4: Internal function updates (3 tasks) - Testing (5 tasks) Build status: All unit tests pass, all e2e tests pass, binary builds successfully.
Reset progress tracking and update spec/tasks for the next phase of work focused on removing legacy code retained from the CLI refactoring.
Create comprehensive task list and progress notes for removing ~900 lines of legacy code from the JSON config-based CLI. Tasks cover 6 phases: removing legacy functions, types, and constants; simplifying naming by dropping WithOptions suffixes; cleaning up tests; and updating documentation. All tasks marked as pending, ready for systematic cleanup execution.
Remove 9 legacy functions from config.go: - getDefaultConfig(), LoadConfig(), loadConfigFromFile() - LoadConfigWithOptions(), Config.Save(), Config.GetMapping() - Config.ShouldIgnore(), Config.Validate(), DetermineSourceMapping() Remove ensureSourceDirExists() from adopt.go (dead code). Also remove unused encoding/json import from config.go. These legacy functions used the old JSON config system with LinkMappings. The new flag-based system (MergeFlagConfig, LoadFlagConfig) remains. Test failures in config_test.go are expected and will be cleaned up in a later task.
Removed 4 legacy functions from linker.go (~200 lines): - CreateLinks(config *Config, dryRun bool) - RemoveLinks(config *Config, dryRun bool, force bool) - removeLinks(config *Config, dryRun bool, skipConfirm bool) - PruneLinks(config *Config, dryRun bool, force bool) These functions used the old Config struct and are replaced by CreateLinksWithOptions, RemoveLinksWithOptions, and PruneWithOptions.
Removed the legacy Status(config *Config) function from status.go as part of the cleanup effort. StatusWithOptions remains and will be renamed to Status in Phase 0. This removes 93 lines of legacy code. Only test files reference the removed function, which will be cleaned up in Task 25.
Remove Adopt(source string, config *Config, sourceDir string, dryRun bool) from adopt.go (98 lines). This function used the old JSON config system with LinkMappings. The new AdoptWithOptions() function remains and is used by the flag-based CLI interface. Test failures in adopt_test.go are expected and will be cleaned up in Task 26.
Removed Orphan(link string, config *Config, dryRun bool, force bool) from orphan.go (121 lines). Production code uses OrphanWithOptions instead.
Remove ErrNoLinkMappings error constant from errors.go as it was only used by the old JSON-based config system with LinkMappings. The new flag-based config system does not need this validation.
Removed ConfigFileName = ".lnk.json" constant from constants.go. This constant was part of the old JSON-based config system and is no longer used. The new flag-based config system uses FlagConfigFileName instead. Phase 1 (Remove Legacy Types and Constants) is now complete.
Removed 4 legacy test functions that used the old Config type with LinkMappings parameter pattern: - TestCreateLinks - TestRemoveLinks - TestPruneLinks - TestLinkerEdgeCases Kept 3 tests for the new LinkOptions-based API: - TestCreateLinksWithOptions - TestRemoveLinksWithOptions - TestPruneWithOptions File reduced from 1659 lines to 767 lines (892 lines removed).
Step 1 (os.Stat) failure after prior links are already orphaned would skip the rollback path, leaving partial disk state and violating the atomicity guarantee.
…ash skip fires before non-symlink check
…ed orphans on os.Lstat failure
…exicographic order
…sclassifying permission-denied symlinks as broken
…ion error The Section 8 example used "permission denied" paired with the adopt hint, but Section 6 scopes that hint exclusively to regular file/directory collisions.
…ut.md" This reverts commit 0e9d15b.
…mplifyOutput check" This reverts commit 2efb0ee.
Update AGENTS.md, README.md, CHANGELOG.md, and orphan design doc to reflect the new subcommand-based CLI (replacing action flags), required positional source-dir argument, removal of --target/--quiet/--source flags, and removal of .lnkconfig support.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.