Skip to content

feat: config migration system, hook improvements, and AI plan generation#18

Merged
chrissena merged 9 commits intomainfrom
feat/config-migration-hooks-ai-planning
Jan 13, 2026
Merged

feat: config migration system, hook improvements, and AI plan generation#18
chrissena merged 9 commits intomainfrom
feat/config-migration-hooks-ai-planning

Conversation

@chrissena
Copy link
Member

@chrissena chrissena commented Jan 13, 2026

Summary

This PR delivers three major enhancements to git-worktree-tools:

  1. Config Migration System - Automatically detect outdated .worktreerc schemas and guide users through migration with atomic writes, backups, and intelligent suggestions.

  2. Hook System Improvements - Fix critical CWD bug where post-* hooks executed in the main repo instead of the worktree, and add interactive confirmation wizard for hook review.

  3. AI Plan Document Generation - Auto-generate implementation planning documents during PR creation with YAML frontmatter metadata and configurable path templates.

Features

Config Migration (wtconfig migrate)

  • Schema versioning with configVersion field (current: v1)
  • Detection of: missing version, legacy .wtlinkrc files, unknown/deprecated keys
  • Levenshtein-based typo suggestions for unknown config keys
  • Atomic writes with automatic backups in .worktree-backups/
  • CLI flags: --dry-run, --yes, --json
  • 54 unit tests covering migration scenarios

Hook Confirmation Wizard

  • Interactive run/skip/edit prompts for post-worktree, post-pr, post-push hooks
  • CI environment detection (GitHub Actions, GitLab CI, Jenkins, CircleCI, Travis, Buildkite, TeamCity, Azure DevOps, AWS CodeBuild, Bitbucket Pipelines)
  • Smart CWD resolution: post-* hooks now correctly default to worktree directory
  • Configurable timeouts with per-hook overrides

AI Plan Documents (--plan / --no-plan)

  • YAML frontmatter with PR metadata (number, branch, base, status)
  • Configurable path templates: {prNumber}, {slug}, {branch}, {date}, {timestamp}
  • Graceful degradation with template-based fallback when no AI provider configured
  • Path traversal protection for security

Bug Fixes

  • fix(prs): Use actual PR branch name when creating worktree from TUI (was using synthetic pr-<number>)
  • fix(windows): Handle file locking with copy+delete pattern instead of atomic rename
  • fix(test): Wait for menu items instead of header in PTY test (fixes flakiness)

Refactoring

  • Add dependency injection to environment detection modules for better testability
  • Extract CI environment variables to typed constant
  • Refine empty catch blocks to specifically handle ENOENT errors
  • Add comprehensive timeout configuration documentation

Test Coverage

  • 3,016 tests passing across all platforms (Ubuntu, macOS, Windows)
  • 58 files changed with ~9,700 additions
  • New test files:
    • config-migration/*.test.ts (997 lines)
    • hooks/confirmation.test.ts (424 lines)
    • newpr/plan-generator.test.ts (531 lines)
    • newpr/hook-runner.test.ts (190 lines)

Breaking Changes

None. All changes are backward compatible.

Configuration Example

{
  "configVersion": 1,
  "hooks": {
    "post-worktree": {
      "command": "npm install",
      "timeout": 180000,
      "cwd": "{{WORKTREE_PATH}}"
    }
  },
  "ai": {
    "planDocument": true,
    "planPath": "docs/plans/PLAN-{prNumber}-{slug}.md"
  }
}

🤖 Generated with Claude Code

Branch created for: add a detector that can determine when old config layouts/schema are being used and suggest migration. Also improve how the hooks are implemented and how the wizard work with this (i.e. wizard should confirm the post-worktree hook action). Also the working directory for the post-worktree hook should default to the WORKTREE_PATH already. Should also add the ability to create an initial plan doc based off of the description using LLM CLI integration which can be part of the initial PR branch commit.

🤖 Created with newpr
@codecov
Copy link

codecov bot commented Jan 13, 2026

Codecov Report

❌ Patch coverage is 78.42893% with 346 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.71%. Comparing base (5cbe961) to head (dc6cceb).
⚠️ Report is 12 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/cli/wtconfig.ts 4.80% 99 Missing ⚠️
src/lib/config-migration/runner.ts 74.66% 75 Missing ⚠️
src/lib/config-migration/detector.ts 77.33% 68 Missing ⚠️
src/cli/newpr.ts 84.13% 33 Missing ⚠️
src/cli/wtlink.ts 11.53% 23 Missing ⚠️
src/lib/wtconfig/environment.ts 72.54% 14 Missing ⚠️
src/lib/lswt/environment.ts 83.92% 9 Missing ⚠️
src/lib/config-migration/reporter.ts 96.69% 7 Missing ⚠️
src/lib/newpr/args.ts 33.33% 6 Missing ⚠️
src/lib/newpr/hook-runner.ts 89.58% 5 Missing ⚠️
... and 3 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #18      +/-   ##
==========================================
- Coverage   81.97%   81.71%   -0.26%     
==========================================
  Files          72       77       +5     
  Lines       16631    18118    +1487     
  Branches     3688     3953     +265     
==========================================
+ Hits        13633    14805    +1172     
- Misses       2998     3313     +315     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

chrissena and others added 5 commits January 13, 2026 06:24
Add dependency injection pattern to environment detection and action
execution modules to prevent VSCode from opening files during tests.

Changes:
- Add EnvironmentDeps interface to wtconfig/environment.ts
- Add LswtEnvironmentDeps interface to lswt/environment.ts
- Add openPathInEditor/openPathInTerminal to prs/actions.ts deps
- Add wslPathToWindows to action-executors.ts deps
- Update worktree-info files to use git.getStatusOutput()
- Add reset functions for test isolation between test cases
- Include spec documents for planned features

All 1995 lib tests pass with proper mocking.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Previously createWorktreeForPr() used synthetic 'pr-<number>' branch names
instead of the actual PR branch (headBranch). This caused confusion as the
local branch didn't match the remote tracking branch.

- Changed branchName from `pr-${pr.number}` to pr.headBranch
- Updated error message to reference actual branch name
- Added explicit test for branch name requirement
- Created implementation spec document

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement comprehensive config migration system for detecting and
migrating legacy configurations:

- Add configVersion field to WorktreeConfig (current version: 1)
- Create config-migration module with detector, runner, and reporter
- Add 'wtconfig migrate' command with --dry-run, --yes, --json flags
- Update 'wtlink migrate' to delegate with deprecation notice
- Support detection of: missing version, legacy .wtlinkrc, unknown keys
- Include Levenshtein-based typo suggestions for unknown keys
- Atomic writes with backups in .worktree-backups/ directory
- 54 unit tests covering migration scenarios

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…tion

- Add hook confirmation prompts for post-worktree, post-pr, post-push hooks
  - Run/skip/edit options for interactive hook management
  - CI environment detection to skip prompts in non-interactive contexts
- Add AI plan document generation with --plan/--no-plan flags
  - YAML frontmatter with PR metadata
  - Configurable path templates with {prNumber}, {slug}, {branch} variables
- Fix CWD bug: post-* hooks now correctly run in worktree directory
  - Add resolveHookCwd() with smart defaults for worktree-aware hooks
  - Add cwd property to complex hook definitions
- Reorganize spec docs: archive completed specs, consolidate active specs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
On Windows, file handles may not be released immediately after close(),
causing EPERM errors during test cleanup and file operations.

- Add delay after fd.close() on Windows before rename in atomicWriteConfig
- Add retry logic with exponential backoff in test afterEach cleanup

Fixes Windows CI failures in config-migration/runner tests.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Comment on lines +84 to +86
if (options.aiAvailable && !options.nonInteractive) {
return { generate: false, prompt: true, reason: 'AI available, prompting user' };
}

This comment was marked as outdated.

chrissena and others added 2 commits January 13, 2026 20:22
On Windows, fs.promises.rename fails with EPERM when the source file was
recently opened, even after calling fd.close(). The file handle release
is not synchronous on Windows.

Solution: On Windows, use copy+delete pattern instead of atomic rename:
1. Write content to temp file
2. Delete existing target (if exists)
3. Copy temp to target
4. Delete temp file

This avoids the file locking issues while still maintaining atomic-like
behavior (the target is only replaced after successful write).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The waitFor pattern was matching "Git Worktree Tools" in the header
before menu items fully rendered, causing flaky test failures.

Changed pattern from /worktree|main menu|select/i to /list worktree/i
to wait specifically for menu items to render.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces intelligent config migration detection, enhanced post-worktree hook management with confirmation prompts, and AI-powered planning document generation. Additionally, it fixes critical bugs related to git operations and branch naming.

Changes:

  • Config migration system with schema versioning, auto-detection, and guided migration
  • Hook confirmation prompts for post-worktree/post-pr/post-push hooks with smart CWD defaults
  • AI planning integration with LLM CLI tools for auto-generating plan documents
  • Bug fixes: empty commit worktree creation, PR branch naming, and auto-link config files

Reviewed changes

Copilot reviewed 56 out of 58 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/lib/config-migration/* New migration system for detecting and fixing outdated configs
src/lib/hooks/confirmation.ts New hook confirmation prompts for security-conscious workflows
src/lib/newpr/plan-generator.ts AI-powered plan document generation with template variables
src/lib/prs/actions.ts Fixed to use PR headBranch instead of synthetic pr- names
src/cli/newpr.ts Fixed git operations to use repoRoot parameter, integrated plan generation
src/lib/config.ts Added configVersion and linkConfigFiles properties
schemas/worktreerc.schema.json Updated schema for new config properties

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

* Tests for Config Migration Detector
*/

import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import vi.

Suggested change
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
import { describe, it, expect, beforeEach, afterEach } from 'vitest';

Copilot uses AI. Check for mistakes.

import fs from 'fs';
import path from 'path';
import { findRepoConfigFile, getSchemaUrl } from '../global-config.js';
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import findRepoConfigFile.

Copilot uses AI. Check for mistakes.
import fs from 'fs';
import path from 'path';
import { findRepoConfigFile, getSchemaUrl } from '../global-config.js';
import { DEFAULT_MANIFEST_FILE } from '../constants.js';
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import DEFAULT_MANIFEST_FILE.

Copilot uses AI. Check for mistakes.
* Tests for Config Migration Runner
*/

import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import vi.

Copilot uses AI. Check for mistakes.
- Extract CI environment variables to constant in confirmation.ts
- Add AWS CodeBuild and Bitbucket Pipelines to CI detection
- Refine empty catch blocks in runner.ts to specifically handle ENOENT
- Add timeout configuration documentation with examples in executor.ts
- Move completed spec 02-newpr-enhancements.md to archive with status badge

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@chrissena chrissena changed the title feat: add config migration, improve hooks, and AI planning feat: config migration system, hook improvements, and AI plan generation Jan 13, 2026
@chrissena chrissena merged commit 4e79db6 into main Jan 13, 2026
12 checks passed
@github-actions
Copy link
Contributor

🎉 This PR is included in version 1.9.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants