mirror of
https://github.com/max-sixty/worktrunk.git
synced 2026-09-14 20:00:38 +08:00
codex/remove-codex-cloud-specific-tests
165 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
491108a782 |
Document hooks in user config (#1845)
The user config (`~/.config/worktrunk/config.toml`) supports hooks via `OverridableConfig.hooks`, but the user config documentation didn't mention them. The project config docs had a hooks section with the full TOML format reference — this adds a comparable section to user config and deduplicates the project config side. - Added `### Hooks` section to user config docs with the three formats (string, named table, pipeline) and user-vs-project differentiation - Replaced the duplicate TOML block in project config hooks with a cross-reference to the user config section > _This was written by Claude Code on behalf of @max-sixty_ --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
ca5980aee8 |
Remove double-commenting from project config example (#1836)
Same treatment as #1832: move prose descriptions out of TOML code blocks so they don't produce `# #` lines in the generated `wt.example.toml`. Also uncomments `hostname` field with an "Example:" note. > _This was written by Claude Code on behalf of @max-sixty_ --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
3292b4fe08 |
Flatten "Setting overrides" into parent section, remove experimental (#1839)
The "Setting overrides" subsection was the only child of "User project-specific settings" — unnecessary nesting. Merged the override description into the parent paragraph and dropped the `[experimental]` tag. > _This was written by Claude Code on behalf of @max-sixty_ --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
75dd894284 |
Auto-generate wt.example.toml from mod.rs source (#1835)
The project config example file (`dev/wt.example.toml`) was hand-maintained with no sync tests, while the user config example had a robust auto-generation pipeline. This brings both to parity — `mod.rs` is the single source of truth, sync tests generate both example files, and CI catches drift. Hooks documentation (~70 lines of formats, template variables, and per-type examples) replaced with a pointer to `wt hook --help` plus a quick-reference showing all three hook formats (string, named table, pipeline). The example file now focuses on project-specific settings: `list.url`, `forge`, `step.copy-ignored`, and aliases. The sync test infrastructure is refactored from a user-config-specific function into shared `extract_config_section` and `assert_config_example_in_sync` helpers that both tests call. > _This was written by Claude Code on behalf of @max-sixty_ --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
d0e3c2dee0 |
Show defaults uncommented in config example (#1832)
The example config had all TOML values double-commented (`# #`), making them look disabled-within-disabled. Config code blocks in the source markdown now show actual default values uncommented, producing clean single-commented lines in the generated `config.example.toml`. Other fixes: `switch.no-cd` default was shown as `true` but code defaults to `false`; `step.copy-ignored.exclude` was shown as `[".cache/", ".turbo/"]` but defaults to `[]`. > _This was written by Claude Code on behalf of @max-sixty_ Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
b33cc8e9d6 |
Simplify forge detection with [forge] config section (#1826)
SSH host aliases (`git@work-ssh:owner/repo`) corrupt the hostname in
remote URLs but never the path. The previous forge detection code tried
to work around this by searching all remotes, auto-detecting GHE
hostnames, and maintaining multiple resolution strategies. This PR
replaces all of that with a simpler design: derive owner/repo from URL
paths, and let users set `forge.platform` / `forge.hostname` for corner
cases.
## Key changes
**New `[forge]` config section** with `platform` and `hostname` fields.
`ci.platform` is deprecated with migration support. Example configs and
inline help examples updated.
**`fetch_pr_info`** now builds literal API paths from the primary
remote's raw URL instead of relying on `gh`'s placeholder resolution.
`--hostname` only passed when explicitly configured.
**`platform_for_repo`** checks config > branch's remote > primary
remote. No longer searches all remotes. Loads config internally instead
of taking a `platform_override` parameter.
**`find_remote`** matches by owner/repo only (no host required),
handling SSH aliases where the local hostname differs from the API
hostname.
**`CiBranchName::from_branch_ref`** uses `split_once('/')` instead of
iterating `all_remote_urls()`, removing a git call per branch during `wt
list`.
## Deleted
- `resolve_gh_hostname` (GHE auto-detection heuristic)
- `find_forge_remote` (search all remotes by predicate)
- `all_remote_urls()` loop in branch name parsing
- `platform_override` parameter threading through callers
The spec in `src/git/repository/remotes.rs` documents the full design.
> _This was written by Claude Code on behalf of max-sixty_
---------
Co-authored-by: Claude <noreply@anthropic.com>
|
||
|
|
4047079fb2 |
Wrap prompt openers in <task> tags and reword squash template (#1794)
Wraps the opening instruction line in all three LLM prompt templates (commit, squash, summary) in `<task>` XML tags — the only content that wasn't already in XML tags. Also rewords the squash template opener from "Combine these commits into a single commit message" to "Write a commit message for the combined effect of these commits", shifting the framing from mechanical concatenation to synthesis. > _This was written by Claude Code on behalf of @max-sixty_ Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
5c1672932f |
docs: remove deprecated post-create from documentation (#1776)
Replace all `post-create` references with `pre-start` across documentation, skills, example config, and test names. The Rust deprecation handling code (migration, alias, config parsing) remains intact for users with existing configs. Also removes `post-create` from the `wt hook show` value_parser — it was listed as a valid hook type for display even though it's been deprecated. > _This was written by Claude Code on behalf of @max-sixty_ Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
439d79b614 |
feat(config): add copy-ignored exclude patterns (#1667)
Add configurable exclusions to `wt step copy-ignored`, and make the command safer by skipping known tool-state directories by default. - `wt step copy-ignored` always skips built-in excluded directories (VCS metadata like `.jj/`, `.hg/` and tool-state like `.conductor/`, `.worktrees/`) - Users can add more excludes with `[step.copy-ignored] exclude = [...]` in user config, per-project user overrides, or project config (`.config/wt.toml`) - All exclusion sources are combined; scalar config values replace, everything else appends (global first) Closes #1653 > _This was written by Claude Code on behalf of maximilian_ --------- Co-authored-by: worktrunk-bot <254187624+worktrunk-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Maximilian Roos <m@maxroos.com> |
||
|
|
9ad642f874 |
feat: use append semantics for alias merging (#1724)
Per-project alias merging changes from "override on collision" to "append" semantics, matching how hooks merge. When both global and per-project user configs define the same alias name, both commands run in sequence (global first, then per-project). The alias value type changes from `String` to `CommandConfig` — the same type hooks use. This stores each command separately and enables the named-table TOML format for multi-command aliases. Key changes: - `merge_alias_maps()` and `UserConfig::aliases()` use `CommandConfig::merge_append()` on collision - `step_alias()` iterates over `CommandConfig.commands()`, running each command separately (fail-fast on first failure) - `approve_alias_commands()` approves each project-config command individually via the existing batch approval system - Project-vs-user merge stays as override (user wins) for security — only the global-vs-per-project *user* merge uses append > _This was written by Claude Code on behalf of @max-sixty_ --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
efad9312db |
feat!: rationalize hooks — rename post-create, add post-commit, background post-merge (#1679)
Implements the hook rationalization from #1670, establishing a symmetric `pre-` (blocking) / `post-` (background) pattern for every lifecycle event. ## Changes **Rename `post-create` → `pre-start`**: The old name suggested it ran *after* creation, but it actually runs *before* `post-start` as a blocking dependency step. Both names accepted for one release cycle — config deprecation detection, migration file generation, `wt config update` support, and CLI alias all in place. `merge_with` folds old-name hooks into new-name so cross-config combinations don't silently drop hooks. **Add `post-commit` hook**: New background hook firing after successful commits (including squash commits), completing the commit lifecycle pair. Included in approval batches for `wt step commit`, `wt step squash`, and `wt merge`. **Change `post-merge` to background**: Was blocking with `Warn` strategy, now runs in background like all other `post-` hooks. `--foreground` flag available for debugging. The hook table is now a clean symmetric grid: | Event | `pre-` (blocking) | `post-` (background) | |-------|-------------------|---------------------| | start | `pre-start` | `post-start` | | switch | `pre-switch` | `post-switch` | | commit | `pre-commit` | `post-commit` | | merge | `pre-merge` | `post-merge` | | remove | `pre-remove` | `post-remove` | ## Testing 868 lib + 483 bin + 1227 integration tests pass, all 13 lint checks pass. The deprecation has 23 dedicated unit tests covering detection at all three config scopes, migration, empty table filtering, cross-config merge safety, and integration with `wt config show` / `wt config update`. Closes #1670 > _This was written by Claude Code on behalf of max-sixty_ --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
7339e4b283 |
docs: add bare repository worktree-path example and layout guide (#1664)
## Summary
- Add bare repo `worktree-path` example (`{{ repo_path }}/../{{ branch |
sanitize }}`) to config docs alongside existing examples
- Update `repo_path` variable description to note bare repo behavior
- Expand "Bare repository layout" section in tips-patterns: explains why
bare repos suit worktree workflows and documents the `git clone --bare
<url> project/.git` setup
## Test plan
- [x] `cargo run -- hook pre-merge --yes` passes
- [x] Doc sync tests pass
(`test_command_pages_and_skill_files_are_in_sync`,
`test_config_source_generates_example_toml`)
- [x] Help snapshots updated and accepted
> _This was written by Claude Code on behalf of @max-sixty_
Co-authored-by: Claude <noreply@anthropic.com>
|
||
|
|
ce9ea1a6b6 |
refactor: consolidate .git/wt-* paths under .git/wt/ and stage removed worktrees in trash (#1583)
## Summary - Moves the rename-based staging directory from a visible sibling path (`project.wt-removing-<timestamp>`) into `.git/wt/trash/`, hiding it from the user's workspace - Consolidates all worktrunk-managed `.git/wt-*` directories under a single `.git/wt/` parent - Adds `Repository::wt_dir()` accessor as the single root for all worktrunk state - Renames `wt-relocate-tmp` to `wt/relocate-staging` for consistency with `wt/promote-staging` - Falls back to legacy `git worktree remove` if the trash directory can't be created - The `.git/` directory is always on the same filesystem as worktrees, so the instant rename guarantee is preserved ## Path migration | Before | After | |--------|-------| | `.git/wt-logs/` | `.git/wt/logs/` | | `.git/wt-cache/summaries/` | `.git/wt/cache/summaries/` | | `.git/wt-cache/ci-status/` | `.git/wt/cache/ci-status/` | | `.git/wt-promote-staging/` | `.git/wt/promote-staging/` | | `.git/wt-relocate-tmp/` | `.git/wt/relocate-staging/` | | (new) `.git/wt/trash/` | Staging for background removal | ## Context Users reported confusion when seeing `.wt-removing-*` directories in their workspace after `wt remove` (#1572). By staging in `.git/wt/trash/` instead, the directory is completely hidden — even if the background `rm -rf` is slow or gets interrupted. The `.git/wt-*` sibling directories were also consolidated into `.git/wt/` for tidiness per review feedback. ## Test plan - [x] Unit tests for `generate_removing_path` and `build_remove_command_staged` updated and passing - [x] All 105 remove-related integration tests passing - [x] `test_remove_background_path_gone_immediately` — verifies instant removal still works - [x] `test_remove_background_fallback_on_rename_failure` — verifies fallback when staging path is blocked - [x] `test_remove_stale_staging_dir_from_crashed_removal` — verifies stale dirs land inside `.git/` - [x] All 2496 tests pass (lib + bin + integration) - [x] Help snapshots, doc sync, and lint checks all pass Closes #1572 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: worktrunk-bot <254187624+worktrunk-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Maximilian Roos <5635139+max-sixty@users.noreply.github.com> |
||
|
|
799aab0eb9 | merge: add --no-ff flag for merge commit (semi-linear history) (#1438) | ||
|
|
7512d8695e |
Add opencode, llm, and aichat to example config (#1533)
Follow-up to #1531. These three tools were only documented in `llm-commits.md` — adding them as double-commented entries in the config example makes them discoverable via `wt config create` and keeps all tool commands in one place, verified by the existing sync test. > _This was written by Claude Code on behalf of @max-sixty_ Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
5a2895cd03 |
Add LLM tool commands to example config as single source of truth (#1531)
The Claude/Codex recommended commands were duplicated across 4 locations (Rust code, llm-commits.md, config.md, Taskfile) with no automated sync — they were already drifting (missing `CLAUDECODE=` prefix, missing `-c system_prompt=''`). Now the double-commented entries in `config.example.toml` are the single source of truth. `recommended_config()` parses them at runtime via `include_str!` + `LazyLock`, and a new sync test verifies `llm-commits.md` matches. Also fixes the existing drift in all copies. > _This was written by Claude Code on behalf of @max-sixty_ --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
7834271528 |
Unify timeout model for list and switch picker (#1515)
The picker had its own hardcoded 200ms per-command timeout default plus a `WORKTRUNK_PICKER_BUDGET_MS` env var escape hatch, while `wt list` had a separate experimental `[list] timeout-ms` for per-task timeouts. This consolidates into a shared config model with clear separation between per-task and wall-clock timeouts. **New config model:** - `[list] task-timeout-ms` — per-task command timeout, shared by both list and picker (default: disabled) - `[list] timeout-ms` — wall-clock budget for list's collect phase (default: disabled) - `[switch.picker] timeout-ms` — wall-clock budget for picker (default: 500ms, was 200ms per-command) The picker's old per-command timeout goes away — the wall-clock budget is sufficient. `collect_deadline` moves from a `collect()` parameter into `ShowConfig::Resolved` where it belongs. Removes the `WORKTRUNK_PICKER_BUDGET_MS` env var and a dead benchmark that tested a non-functional env var. Note: `[list] timeout-ms` changes semantics from per-task to wall-clock budget. The old field was marked "(Experimental)" and not shown in user-facing docs. > _This was written by Claude Code on behalf of max-sixty_ Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
0760817af7 |
feat(docs): style experimental markers as badge pills (#1499)
Replaces plain `[experimental]` text in web docs with styled pill badges — small uppercase labels with a subtle border that read as metadata rather than emphasis. Canonicalizes all experimental markers to `[experimental]` (was a mix of `[experimental]`, `(experimental)`, `(Experimental)`). One marker format in cli.rs, one `.replace()` in the post-processing. Also renames `colorize_ci_status_for_html` → `post_process_for_html` (it handles badges and URLs too), adds a module docstring documenting the full `--help-page` pipeline, and fixes a latent double-application of the post-processor on subdoc content. > _This was written by Claude Code on behalf of @max-sixty_ --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
00eb04a042 | feat(switch): add no-cd config option (#1401) | ||
|
|
55bc9188b4 |
feat(step): add alias command for user-defined command templates (#1348)
## Summary
- Adds `wt step <alias-name>` for running user-defined command templates
configured in `[aliases]` sections of user or project config
- Aliases support the same template variables as hooks (`{{ branch }}`,
`{{ worktree }}`, etc.) plus custom `--var KEY=VALUE` variables
- Project-config aliases require the same command approval flow as
project hooks; user-config aliases are trusted. `--dry-run` skips
approval since it's a read-only preview
- Alias names matching built-in step commands are filtered from the
"available" list in error messages (shadowed by the built-in)
- Introduces `Phase` enum (`Hook(HookType)` | `Alias`) replacing the old
`hook_type` + `phase_override` pattern in the approval system
- Renames `HookCommand` to `ApprovableCommand` since it now covers both
hooks and aliases
## Test plan
- [x] Unit tests for `AliasOptions::parse` (name-only, --dry-run, --yes,
--var, empty key rejection, positional arg rejection)
- [x] Integration tests for alias execution, dry-run (without --yes),
exit code propagation
- [x] Integration tests for shadowing (filtered from available list)
- [x] Integration tests for user/project config merging
- [x] Integration tests for approval flow (project prompts, user skips,
override skips, already-approved, --yes bypass, decline)
- [x] Unit tests for `merge_alias_maps` coverage
- [x] Sync test: `BUILTIN_STEP_COMMANDS` matches actual `StepCommand`
clap variants
> _This was written by Claude Code on behalf of max-sixty_
---------
Co-authored-by: Claude <noreply@anthropic.com>
|
||
|
|
8587b66080 |
docs: update stale documentation and fix version snapshot filter (#1113)
## Summary - Remove stale "Approved hook commands" subsection from config docs — approvals moved to `approvals.toml` and no longer belong in the user config section - Fix version regex filters in test infra that failed to handle `-dirty` suffix on bare hash versions (when `git describe` has no reachable tags), making snapshots non-deterministic - Add `commands.jsonl` documentation to `wt config state logs` help text - Add "Documentation accuracy" checklist to PR review skill - Remove deleted `test_clone_bare_repo_list_no_status_errors` (covered by #1112's `BareRepoTest`) - Minor cleanup: remove "select" from CLAUDE.md command list, remove stale pre-release-replacements, update skill version marker ## Test plan - [x] All 1084 tests pass locally - [x] Pre-commit lints pass - [x] Snapshot tests reviewed — version snap now shows `wt [VERSION]` (not `wt [VERSION]-dirty`), config help snaps reflect removed approvals section - [x] Doc sync test passes (`test_command_pages_and_skill_files_are_in_sync`) > _This was written by Claude Code on behalf of @max-sixty_ --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
91a505603a |
feat: add Summary column to wt list --full (#1100)
## Summary - Adds an LLM-generated Summary column to `wt list --full`, showing a one-line description of each branch's changes - Extracts shared summary module (`src/summary.rs`) from picker-specific code for reuse across `wt list` and `wt switch` - Summary and Message are both flexible columns — Summary expands first (10→70 chars), then Message gets remaining space (10→100 chars) - Gated on `[list] summary = true` config (disabled by default — each branch's diff is sent to the configured LLM) plus `[commit.generation]` and `--full` - Labeled as experimental throughout docs ## Test plan - [x] 539 unit tests pass - [x] 1072 integration tests pass (including 9 new layout tests for flexible Summary/Message allocation) - [x] Pre-commit lints pass - [x] Manual: `wt list --full` with LLM configured + `summary = true` — Summary column appears - [x] Manual: `wt list --full` without `summary = true` — no Summary column - [x] Manual: `wt list` (no `--full`) — no Summary column - [x] Manual: `wt switch` picker — summary tab still works > _This was written by Claude Code on behalf of max-sixty_ 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
41eaf85aad |
feat: add [switch.picker] config with configurable timeout (#1087)
## Summary - Migrate `[select]` config → `[switch.picker]` with backward compat and deprecation guidance - Add `timeout-ms` to `[switch.picker]` (default: 200ms, `0` = no timeout) replacing the hardcoded 500ms picker command timeout - Add `test_config_docs_include_all_sections` to catch undocumented config sections ## Test plan - [x] 530 unit tests pass - [x] 1058 integration tests pass - [x] All lints pass (pre-commit) - [x] Help text snapshots updated - [x] Docs, example config, and skills auto-synced - [x] Deprecation detection and TOML migration tested (including snapshot) > _This was written by Claude Code on behalf of @max-sixty_ 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
74e3d6baf8 |
feat(switch): add AI summary preview tab (#1049)
* feat(switch): add AI summary preview tab (tab 5) Add a fifth preview mode to `wt switch` that shows AI-generated branch summaries using the configured [commit.generation] LLM command. Summaries use commit-message format (imperative subject + body) and render through the standard markdown help renderer for consistent styling. - Background thread generates summaries in parallel for all branches - Disk cache in .git/wt-cache/summaries/ with hash-based invalidation - Graceful fallback: config hint when LLM not configured, dim "no changes" for default branch - Shortened tab labels to fit 5 tabs: 1:diff | 2:log | 3:main | 4:upstream | 5:summary Co-Authored-By: Claude <noreply@anthropic.com> * fix: resolve merge conflicts from jj revert After merging main (which reverted jj support), fix two issues: - Resolve config to access commit_generation (handle_select no longer receives resolved config directly) - Restore pub(crate) visibility on execute_llm_command Co-Authored-By: Claude <noreply@anthropic.com> * test: add cache and rendering tests for summary module Add tests for cache round-trip, hash invalidation, file path sanitization, directory structure, and pre-styled text rendering to improve codecov/patch coverage. Co-Authored-By: Claude <noreply@anthropic.com> * test: add integration test for summary tab and expand cache tests - Add PTY test for tab 5 showing config hint when LLM not configured - Add cache round-trip, invalidation, sanitized path, and dir tests - Add pre-styled text rendering test for dim "no changes" messages Co-Authored-By: Claude <noreply@anthropic.com> * test(summary): add coverage for diff computation and LLM generation Add 10 new unit tests covering `compute_combined_diff`, `generate_summary`, `generate_all_summaries`, and the single-line `render_summary` path. Uses real temp git repos with shell-stub LLM commands (following existing patterns from merge integration tests). Also refactors test helpers to share git command setup and repo initialization, eliminating duplication between test cases. Co-authored-by: Claude <noreply@anthropic.com> * fix(summary): handle missing default branch + add coverage tests - compute_combined_diff no longer bails when default_branch() returns None — wraps branch diff in if-let, preserving working tree diff - Fix test to use exotic branch name so default_branch() actually returns None (infer_default_branch_locally checks "main"/"master"/etc) - Add unit tests for items.rs Summary tab paths (main worktree, feature branch, cache hit/miss, compute_preview delegation) - Add error path tests for write_cache (unwritable path, permission failure) Co-Authored-By: Claude <noreply@anthropic.com> * fix(summary): address PR review feedback - Remove is_main() shortcut from compute_summary_preview — was checking main worktree (git concept) not default branch (different concept) - Add unicode visual cues to tab labels: 1:diff±, 3:main↕, 4:upstream⇅ - Move summary_items clone closer to its consumer in mod.rs Co-Authored-By: Claude <noreply@anthropic.com> * fix(ci): revert unicode tab cues — ambiguous East Asian Width Characters ±, ↕, ⇅ have East Asian Width "Ambiguous" which skim renders as double-width on CI, shifting [N/M] alignment by 3 chars. Revert to plain labels for cross-platform consistency. Co-Authored-By: Claude <noreply@anthropic.com> * fix(switch): restore unicode symbols in tab labels Restore ±, ↕, ⇅ symbols to tab labels (1:diff±, 3:main↕, 4:upstream⇅). These characters are used throughout the codebase and haven't shown width issues in practice. Co-authored-by: Maximilian Roos <max-sixty@users.noreply.github.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor(summary): bound concurrent LLM calls with Semaphore Use the project's existing Semaphore (from src/sync.rs) to limit concurrent LLM calls to 8 — same pattern as HEAVY_OPS_SEMAPHORE and CMD_SEMAPHORE. Co-authored-by: Maximilian Roos <max-sixty@users.noreply.github.com> * fix(switch): adjust snapshot spacing for unicode tab symbols skim-tuikit uses width_cjk() for header layout, which treats East Asian Width "Ambiguous" characters (±, ↕) as double-width. This shifts [N/M] left by 3 columns. Update snapshots to match. Co-authored-by: Maximilian Roos <max-sixty@users.noreply.github.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(test): normalize tab bar padding for cross-platform unicode widths Skim right-aligns the [N/M] count indicator with padding that varies depending on whether unicode chars (±, ↕, ⇅) are rendered as single or double width. Normalize this padding in the snapshot filter so tests pass regardless of the terminal's East Asian Width handling. Co-authored-by: Maximilian Roos <max-sixty@users.noreply.github.com> * fix(switch): restore original tab titles, add 5th summary tab Revert tab labels 1-4 to their original format ("1: HEAD±", "2: log", "3: main…±", "4: remote⇅") and add "5: summary" as a new 5th tab. Co-authored-by: Maximilian Roos <max-sixty@users.noreply.github.com> * fix(test): handle skim count overlap with summary tab label When the 5 restored tab labels use ambiguous-width unicode symbols (±, …, ⇅), skim's width_cjk() treats them as double-width, leaving insufficient space for the count indicator. This causes the count to overlap with "summary" (e.g., "summary1/4") or truncate it ("summar1/28"). Add a targeted regex filter that normalizes this overlap before the generic whitespace-padded count filter runs. Co-authored-by: Maximilian Roos <max-sixty@users.noreply.github.com> * fix(test): avoid typos lint on truncated word in snapshot regex Use `summary?` (optional `y`) instead of `summar` to avoid the typos spell checker flagging the partial word. Co-authored-by: Maximilian Roos <max-sixty@users.noreply.github.com> * fix(ci): restructure review skill workflow and fix dead sticky comment (#1056) - Reorder as explicit numbered workflow: pre-flight checks before expensive diff analysis to avoid redundant work - Remove redundant "read CLAUDE.md" (already in system prompt) - Filter dedup check by bot identity so human approvals don't cause the bot to skip its review - Accept brief approval bodies (matches actual bot behavior) - Replace {owner}/{repo} placeholders with derived $REPO variable - Add --paginate on comment fetching for large PRs - Remove sticky comment references from skill (bot puts feedback in review bodies, not stdout — sticky comment stopped working after PAT switch in #1052) - Add TODO on use_sticky_comment in workflow - Restore gh pr comment prohibition with correct justification Co-authored-by: Claude <noreply@anthropic.com> * fix(shell): harden nushell wrapper and improve diagnostics (#1059) * fix(shell): harden nushell wrapper and improve diagnostics - Move LAST_EXIT_CODE capture inside do{} block so it reflects the actual command exit code, not a subsequent operation - Wrap directive processing in try/catch to ensure temp file cleanup on error - Include nushell vendor autoload paths in scan_for_detection_details so `wt config show` reports nushell integration status - Add "nu" to the supported shells hint shown on unsupported shells - Fix detection tests to use actual nushell config line patterns - Document why non-cd directives delegate to sh -c Co-Authored-By: Claude <noreply@anthropic.com> * refactor(shell): remove try/catch from nushell directive cleanup Drop error-path cleanup for the temp directive file. On error, the file persists in /tmp as a useful debugging artifact (the OS cleans it up). This matches bash and fish which already use a single rm on the happy path with no error wrapping. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> * fix(shell): PowerShell wrapper swallows -D flag as -Debug (#1057) * fix(shell): PowerShell wrapper swallows -D flag as -Debug (#885) The `[Parameter(ValueFromRemainingArguments)]` attribute promoted the wrapper to an "advanced function", which adds common parameters like -Debug and -Verbose. PowerShell then consumed `-D` as `-Debug` instead of passing it to wt.exe — so `wt remove -D` silently lost the flag. Replace with `$args` (automatic variable for simple functions) which passes all arguments through unchanged. Co-Authored-By: Claude <noreply@anthropic.com> * fix(test): use .ps1 mock for cross-platform PowerShell test The shell script mock (#!/bin/sh) doesn't work on Windows. Use a .ps1 script instead — pwsh can invoke it directly with &, and pwsh is already required for this test. Co-Authored-By: Claude <noreply@anthropic.com> * style: apply cargo fmt to PowerShell test Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> * fix(ci): use empty body for LGTM approvals instead of fluff (#1060) The review bot was generating summary prose like "Clean hardening of the nushell wrapper..." when it had no issues to raise. An empty approval is less noisy — the thumbs-up reaction is sufficient signal. Co-authored-by: Claude <noreply@anthropic.com> * fix(list): handle empty repos (no commits) gracefully (#1058) * fix(list): handle empty repos (no commits) gracefully Skip commit-dependent tasks for unborn branches (null OID) using a COMMIT_TASKS constant, following the existing EXPENSIVE_TASKS pattern. Filter null OIDs from timestamp batching, accept unborn default branch in validation, and render empty commit/age cells instead of garbage. Closes #885 Co-Authored-By: Claude <noreply@anthropic.com> * fix: address codecov/patch coverage gaps - Remove unreachable COMMIT_TASKS check from work_items_for_branch (null OIDs only appear in worktree HEAD, never in git for-each-ref) - Restructure json_output null OID handling to eliminate dead branch - Pre-set default branch config in test to exercise is_unborn_head_branch path Co-Authored-By: Claude <noreply@anthropic.com> * fix: remove unused BranchRef::has_commits() (dead code) Only WorktreeInfo::has_commits() is called in the dispatch code. BranchRef::has_commits() was never referenced, causing a codecov gap. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> * refactor(switch): unify preview mode handling All 5 preview modes now follow the same cache → compute → post-process path in preview_for_mode, eliminating the Summary early-return special case. Summary precomputation uses rayon (queued after tabs 1-4) instead of a separate std::thread::spawn + thread::scope wrapper. Threading simplified from: rayon::spawn × (N × 4) ← tabs 1-4 std::thread::spawn ← wrapper └── std::thread::scope ← N scoped threads └── LLM_SEMAPHORE ← rate limit To: rayon::spawn × (N × 4) ← tabs 1-4 (queued first) rayon::spawn × N ← summaries (queued last, semaphore inside) Co-Authored-By: Claude <noreply@anthropic.com> * feat(switch): gate summary tab behind [list] summary config Summary generation is opt-in via `[list] summary = true` (default: false) to avoid surprise LLM calls for users who have `[commit.generation]` configured. Both settings are required for summaries to fire. Adds documentation for the feature in switch help, FAQ (commands we run), and llm-commits page (new "Picker summaries" section). Co-Authored-By: Claude <noreply@anthropic.com> * fix: use ResolvedConfig directly after main merge The merge with main changed handle_select to receive ResolvedConfig instead of UserConfig, so the .resolved() call is no longer needed. Co-Authored-By: Claude <noreply@anthropic.com> * test: update summary preview snapshot for config hint The hint text now includes [list] summary = true in addition to the [commit.generation] example. Co-Authored-By: Claude <noreply@anthropic.com> * fix: replace missed shlex::try_quote with shell_escape The shlex removal in #1065 missed one call site in the switch suggestion context builder. Replace with shell_escape::escape to match the rest of the codebase. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: Maximilian Roos <max-sixty@users.noreply.github.com> |
||
|
|
600da7101b |
Refactor approvals into separate file with deprecation migration (#1042)
* Refactor approvals into separate file Approved commands are now stored in `~/.config/worktrunk/approvals.toml`, independent of user config. This enables dotfile management of `config.toml` without exposing machine-local trust state. The `Approvals` type provides the same mutation interface as `UserConfig` (approve/revoke commands, file locking) but stores exclusively approval data. For backward compatibility, approvals are silently read from `config.toml` if `approvals.toml` doesn't exist. All command approval code now uses `Approvals::load()` and passes `&approvals` to `approve_command_batch()`. Tests use isolated `test_approvals_path()` to prevent pollution of user approvals. * Add deprecation warning for approved-commands in config.toml Approved commands moved to approvals.toml in the previous commit but stale entries in config.toml were silently ignored. Now `wt config show` detects them, generates a migration file that removes the entries, and shows a diff + mv command. Other commands show a brief warning. Also updates all CLI help text, docs, and FAQ to reference approvals.toml as the storage location, and migrates all test configs to use write_test_approvals() for approved-commands content. Co-Authored-By: Claude <noreply@anthropic.com> * fix: document fallback path asymmetry and add config.toml fallback tests Address PR review feedback: - Document why `load_from_config_fallback()` uses `get_config_path()` while `reload_from()` uses sibling derivation, and why both converge in production - Add `test_load_from_config_file` testing the extraction logic - Add `test_mutation_picks_up_config_toml_fallback` testing the full mutation path with config.toml fallback (no approvals.toml → reads config.toml → preserves existing commands alongside new one) - Inline `get_config_path` import (only used in `#[cfg(not(test))]` block) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: single fallback path for config.toml approvals Replace two separate fallback implementations (load_from_config_fallback via get_config_path, and reload_from via sibling derivation) with a single load_with_fallback(path) that both load() and reload_from() use. The shared helper derives config.toml as a sibling of the approvals file, which is always correct since get_approvals_path() derives approvals.toml as a sibling of config.toml. Co-Authored-By: Claude <noreply@anthropic.com> * fix(tests): pass WORKTRUNK_APPROVALS_PATH in shell wrapper tests Shell wrapper tests only passed WORKTRUNK_CONFIG_PATH to the binary, so it derived the approvals path from config and found approved-commands in config.toml, triggering the new deprecation warnings. This broke 4 snapshot tests and likely caused 6 timeouts on CI. Fix: pass WORKTRUNK_APPROVALS_PATH alongside WORKTRUNK_CONFIG_PATH in all shell wrapper test environments (build_shell_script, build_test_env_vars, and custom script builders for all shell types). Migrate all approved-commands writes from test_config_path() to write_test_approvals(). Co-Authored-By: Claude <noreply@anthropic.com> * fix(docs): escape brackets in doc comments for rustdoc Rustdoc interprets `[projects]` as a broken intra-doc link. Escape with `\[...\]` to treat as literal text. Co-Authored-By: Claude <noreply@anthropic.com> * fix(tests): migrate approvals in e2e_shell_post_start and approval_pty tests - e2e_shell_post_start: write approved-commands to approvals.toml instead of config.toml (fixes 5 timeout failures from unanswered approval prompts) - approval_pty permission test: use a subdirectory for the read-only approvals path so the temp root stays writable for .zshrc and other test files Co-Authored-By: Claude <noreply@anthropic.com> * test: improve coverage for approvals and deprecation modules Add tests covering error paths, edge cases, and new deprecation features: - approvals.rs: load_from_file parse errors, load_from_config_file parse errors, load_from_path nonexistent, revoke on nonexistent projects, clear_all when empty, save_to with empty project, revoke_project with empty commands - deprecation.rs: remove_approved_commands with invalid TOML, format_deprecation_details with approved_commands flag, write_migration_file with approved_commands Co-Authored-By: Claude <noreply@anthropic.com> * refactor: remove unused revoke_command from Approvals Adversarial review found a normalization bug: revoke_command used exact string matching while is_command_approved normalizes template variables. Rather than fix a method with no production callers, remove it entirely. Production code uses revoke_project (removes all approvals for a project) and clear_all. Rewrote test_concurrent_revoke_preserves_all_changes to use revoke_project. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
0c9e0205a3 |
feat(switch): integrate interactive picker into wt switch (#894)
* feat(switch): integrate interactive picker into `wt switch` (#890) `wt switch` without arguments now opens the interactive picker (previously `wt select`). This simplifies the mental model: one command for all switching. - `wt switch` → opens interactive picker (Unix) or shows error (Windows) - `wt switch --branches/--remotes` → customizes picker - `wt select` → deprecated hidden alias with warning Removes the separate `wt select` docs page since the functionality is now documented under `wt switch`. The `[select]` config section is preserved for backward compatibility with a TODO to rename once migration is confirmed. Closes #890 Co-Authored-By: Claude <noreply@anthropic.com> * fix(test): make switch TTY test Unix-only The test expects the Unix error message ("Interactive picker requires an interactive terminal") but Windows shows a different message ("Interactive picker is not available on Windows"). Co-Authored-By: Claude <noreply@anthropic.com> * chore: trigger CI Co-Authored-By: Claude <noreply@anthropic.com> * fix(switch): require branch when using --create, --base, --execute, or --clobber These flags only make sense when switching to a specific branch, not when opening the interactive picker. Previously, running `wt switch --create` would silently ignore the flag and open the picker instead. Now clap properly enforces that these flags require a branch argument: $ wt switch --create error: the following required arguments were not provided: <BRANCH> Co-Authored-By: Claude <noreply@anthropic.com> * fix(test): update snapshot for interactive picker error message The snapshot was stale after integrating `wt select` into `wt switch`. Now `wt switch` without args shows the picker error, not clap's missing argument message. Co-Authored-By: Claude <noreply@anthropic.com> * docs(switch): move interactive picker section after shortcuts The picker is a navigation method (like shortcuts), not an afterthought. New order: Shortcuts → Interactive picker → GitHub/GitLab PRs → Troubleshooting Co-Authored-By: Claude <noreply@anthropic.com> * fix(test): update help snapshot after doc reorg Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
4bf73ae6fb |
feat(config): support absolute paths in worktree-path template (#904)
* feat(config): support absolute paths in worktree-path template
Add {{ repo_path }} variable to worktree-path templates, enabling
absolute path configurations. The new default template uses this
variable to produce canonical absolute paths.
Changes:
- Remove validation that rejected absolute paths
- Add repo_path variable to format_path() template expansion
- Change default from "../{{ repo }}.{{ branch | sanitize }}" to
"{{ repo_path }}/../{{ repo }}.{{ branch | sanitize }}"
- Update documentation and tests
Existing relative paths continue to work unchanged.
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(config): use native path format for repo_path template variable
Address review feedback from Codex:
- Use native path format instead of POSIX for repo_path variable, since
it's used for filesystem operations, not shell commands
- Rename misleading `relative_path` to `expanded_path` in resolve.rs
- Add .trim() to worktree-path empty validation to catch whitespace-only
- Make tests cross-platform by using std::path::MAIN_SEPARATOR
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(tests): make format_path tests cross-platform
Don't rely on platform-specific path separators in test assertions.
The template uses forward slashes which work on all platforms, but
mixing with native paths creates inconsistent results.
Co-Authored-By: Claude <noreply@anthropic.com>
* docs: lead with absolute paths in worktree-path examples
Remove /tmp example and make relative paths a minor detail at the end.
Co-Authored-By: Claude <noreply@anthropic.com>
* feat: expand ~ to home directory in worktree-path templates
Enables patterns like:
worktree-path = "~/worktrees/{{ repo }}/{{ branch | sanitize }}"
Co-Authored-By: Claude <noreply@anthropic.com>
* docs: simplify relative path note
Co-Authored-By: Claude <noreply@anthropic.com>
* test: verify PathBuf::join replaces base with absolute path
Documents the behavior we rely on for absolute worktree-path templates.
Co-Authored-By: Claude <noreply@anthropic.com>
* revert: remove std behavior test
The template tests already verify absolute paths work correctly.
Co-Authored-By: Claude <noreply@anthropic.com>
* test(bare): add test for {{ repo_path }} variable in bare repos
Verifies that absolute path templates using {{ repo_path }} work
correctly with bare repositories. For bare repos, repo_path resolves
to the bare repo directory itself.
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
|
||
|
|
3d69cec1a7 |
fix(docs): correct broken worktrunk.dev URLs in templates (#882)
- fish_wrapper.fish: /docs/shell-integration → /config/#shell-integration - config.example.toml: /config.md#project-configuration/ → /config/#project-configuration - Remove worktrunk.dev from lychee exclusions so future broken links are caught Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
e154b9ee50 |
Add LLM setup prompt for first-time commit configuration (#867)
* Add LLM setup prompt for first-time commit configuration Implement one-time interactive prompt when users attempt commit/merge/squash without LLM configuration. Detects available tools (claude, codex) and offers auto-configuration with preview on `?`. Adds `skip-commit-generation-prompt` flag to suppress re-prompting, `set_commit_generation_command()` config method, and reusable `prompt_yes_no_preview()` utility. Updates commit message templates to clarify format requirements, fixes Claude Code command syntax (spaces to equals in flags), and adds visual styling to section headers in documentation. * Update snapshots for template format changes Co-Authored-By: Claude <noreply@anthropic.com> * Simplify commit template format guidance Remove redundant trivial-changes line from template format section. Fix duplicate "# Other" header from merge. Document skip-commit-generation-prompt in first-run prompts section alongside skip-shell-integration-prompt. Co-Authored-By: Claude <noreply@anthropic.com> * Add unit tests for command detection functions Cover command_exists() and detect_llm_tool() with basic unit tests to improve test coverage on the commit generation module. Co-Authored-By: Claude <noreply@anthropic.com> * Add PTY tests for commit generation prompt Test the interactive prompt flow for LLM commit configuration: - No tool found → sets skip flag - User declines → sets skip flag - User accepts → saves config - User requests preview → shows preview Uses fake claude script to test the prompt path that requires a detected LLM tool. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
d9ced70893 |
docs(config): reapply H1 major sections with hero fix (#862)
* docs(config): add H1 major sections with TOC support (#857) * docs(config): add H1 major sections with TOC support Add H1 headings for major sections (User Configuration, Project Configuration, Shell Integration, Environment Variables) to improve navigation and visual hierarchy. Theme changes: - Include H1s in sidebar TOC with divider lines - Fix H1 link color (was orange due to missing zola-anchor rule) - Style H1 headings consistently with H2 (underline, size) Co-Authored-By: Claude <noreply@anthropic.com> * docs(config): improve TOC structure and auto-generate Subcommands header - Auto-insert "# Subcommands" in help.rs before subdoc expansions - Add "# Other" section containing Environment Variables and Command reference - Rename "Commands" to "Command config" for clarity - Fix TOC styling: align H1/H2 text, reduce vertical spacing, use sentence case - Template: show H2s nested under H1s at same indent as standalone H2s Co-Authored-By: Claude <noreply@anthropic.com> * fix: address codex review feedback - Add default guard for h.children in TOC template - Remove ineffective :first-of-type selector Co-Authored-By: Claude <noreply@anthropic.com> * docs: use sentence case for Environment variables Co-Authored-By: Claude <noreply@anthropic.com> * test: update snapshots for config section header changes Co-Authored-By: Claude <noreply@anthropic.com> * test: update help_config_create snapshot Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> * fix(docs): prevent h1 styling from breaking hero layout The H1 major sections commit added `width: fit-content` and underline styling to all h1 elements. This broke the hero because: - fit-content shrinks the element, breaking text-align: center - The underline appeared on the hero title Fix by overriding these in .heading-text (used for page titles/hero): - width: auto to restore centering - > a::after { display: none } to hide underline Co-Authored-By: Claude <noreply@anthropic.com> * fix(docs): align H1 TOC entries with H2s Remove left border and custom padding from H1 entries in the sidebar TOC. H1s are now distinguished only by bolder weight and extra top margin, creating a cleaner visual hierarchy. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
400f22d2c0 |
Revert "docs(config): add H1 major sections with TOC support (#857)"
This reverts commit
|
||
|
|
5d831694dd |
docs(config): add H1 major sections with TOC support (#857)
* docs(config): add H1 major sections with TOC support Add H1 headings for major sections (User Configuration, Project Configuration, Shell Integration, Environment Variables) to improve navigation and visual hierarchy. Theme changes: - Include H1s in sidebar TOC with divider lines - Fix H1 link color (was orange due to missing zola-anchor rule) - Style H1 headings consistently with H2 (underline, size) Co-Authored-By: Claude <noreply@anthropic.com> * docs(config): improve TOC structure and auto-generate Subcommands header - Auto-insert "# Subcommands" in help.rs before subdoc expansions - Add "# Other" section containing Environment Variables and Command reference - Rename "Commands" to "Command config" for clarity - Fix TOC styling: align H1/H2 text, reduce vertical spacing, use sentence case - Template: show H2s nested under H1s at same indent as standalone H2s Co-Authored-By: Claude <noreply@anthropic.com> * fix: address codex review feedback - Add default guard for h.children in TOC template - Remove ineffective :first-of-type selector Co-Authored-By: Claude <noreply@anthropic.com> * docs: use sentence case for Environment variables Co-Authored-By: Claude <noreply@anthropic.com> * test: update snapshots for config section header changes Co-Authored-By: Claude <noreply@anthropic.com> * test: update help_config_create snapshot Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
16c29b48bf |
docs(config): fix project config anchor links
Update anchor links from "worktrunk-project-configuration" to "project-configuration" across documentation and code files. |
||
|
|
79fe892bfa |
feat: add per-project hooks with append semantics (#842)
* feat: add per-project hooks with append semantics Per-project hooks in user config now append to global hooks rather than replacing them. Execution order: global → per-project → project. Also: - Move hooks into OverridableConfig for consistency - Rename UserConfig.overrides to UserConfig.configs - Add schemars for deriving valid config keys from JsonSchema - Replace manual VALID_USER_CONFIG_KEYS with schema-derived function Co-Authored-By: Claude <noreply@anthropic.com> * refactor: unify config validation on JsonSchema Both UserConfig and ProjectConfig now use JsonSchema-derived keys for validation instead of serde HashMap catchall. This: - Removes `unknown` field from ProjectConfig - Removes `unknown()` method from WorktrunkConfig trait - Simplifies `is_valid_key` to not need value parameter - Adds JsonSchema to JSON output types for future schema generation Co-Authored-By: Claude <noreply@anthropic.com> * docs: document per-project hooks in setting overrides section - Add per-project hooks to Setting overrides (Experimental) section - Update hook.md table to show execution order with per-project hooks - Replace JSON context example with one showing complex conditionals - Keep documentation DRY by linking from hook.md to config.md Co-Authored-By: Claude <noreply@anthropic.com> * docs: use consistent terminology (user config, not settings) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
3dd7657880 |
docs: clarify user project-specific settings section (#835)
- Restructure intro paragraph as bullet list for clearer context - Fix casing: "worktrunk" → "Worktrunk" - Fix command: "wt hook approve --clear" → "wt hook approvals clear" Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
ee029d19f1 |
docs: clarify user project-specific settings section (#830)
Restructure the per-project settings documentation to better distinguish between user config and project config. The section now clearly explains the two-config system before introducing per-project user settings as a third category. Key changes: - Rename section from "Per-project settings" to "User project-specific settings" - Add intro establishing user/project config dichotomy - Split into subsections: "Approved hook commands" and "Setting overrides" - Remove misplaced reference to project config hooks - Link to project config documentation for clarity Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
f8aaead5b3 |
refactor: restructure commit-generation config to [commit.generation] (#809)
* refactor: restructure commit-generation config to [commit.generation] - Move `[commit-generation]` to `[commit.generation]` (nested under commit) - Replace `command` + `args` with single `command` string (shell execution) - Add deprecation warning for old format with backward compatibility - Update docs to present Claude CLI and llm as equal options The new format uses shell execution (`sh -c`) so environment variables can be set inline in the command string. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: update tests and docs for new commit.generation config format Fix test regressions identified by Codex review where tests using WORKTRUNK_COMMIT_GENERATION__ARGS were silently failing because args is now ignored with the new shell-based command format. Tests now use the correct pattern: WORKTRUNK_COMMIT_GENERATION__COMMAND="cat >/dev/null && echo 'message'" Also update CLI docs to show: - New config path: commit.generation.command (not commit-generation.command) - New env var format: WORKTRUNK_COMMIT__GENERATION__COMMAND - Remove args documentation (no longer applicable) Co-Authored-By: Claude <noreply@anthropic.com> * fix: update doc comments and add validation for new config path Address Codex review feedback: - Update per-project doc example to show new format (commit.generation instead of commit-generation) - Update env var comment to show new format (COMMIT__GENERATION__COMMAND instead of COMMIT_GENERATION__COMMAND) - Add validation for projects.*.commit.generation path (was only validating deprecated commit-generation path) Co-Authored-By: Claude <noreply@anthropic.com> * fix: address remaining Codex review issues - Use ShellConfig for LLM command execution (Windows compatibility) - Improve error handling when LLM stderr is empty - Format reproduction commands with conditional sh -c wrapping - Update tests to use new env var format (WORKTRUNK_COMMIT__GENERATION__) - Make test assertion more specific ([commit] not just "commit") - Document cformat safety for shell commands in output guidelines Co-Authored-By: Claude <noreply@anthropic.com> * refactor: use shell_escape crate for reproduction command escaping Replace manual single-quote escaping with the shell_escape crate which is already a dependency used elsewhere in the codebase. Co-Authored-By: Claude <noreply@anthropic.com> * feat: unify deprecation handling with single .new migration file Consolidate all deprecation handling into deprecation.rs: - Add [commit-generation] → [commit.generation] section migration - Merge deprecated `args` field into `command` string - Generate single .new file with all migrations (template vars + sections) - Skip migration if new section already exists (don't overwrite) - Skip warning for empty deprecated sections - Use shell_escape for proper quoting when merging args - Rename hint from deprecated-project-config to deprecated-config Remove separate warn_deprecated_commit_generation() from user.rs. Co-Authored-By: Claude <noreply@anthropic.com> * fix: harden commit-generation migration against edge cases Fixes found during adversarial testing: 1. Args data loss prevention: merge_args_into_command() now validates preconditions (args is array, command is string) BEFORE removing the args field. Previously, table.remove("args") happened unconditionally, losing data if command was missing or non-string. 2. Malformed generation detection: When checking if new [commit.generation] exists, now verify it's actually a table (is_table || is_inline_table). A malformed value like `generation = "string"` no longer suppresses deprecation warnings for the old section. 3. Inline table support: Both detection and migration now handle inline table format (e.g., `commit-generation = { command = "..." }`). Detection uses as_inline_table() in addition to as_table(). Migration converts InlineTable to Table via into_table(). Added comprehensive tests for all edge cases. Co-Authored-By: Claude <noreply@anthropic.com> * test: add coverage for project-level inline table migration Add tests for: - Project-level inline table migration - Preserving existing [commit] fields during migration - Empty inline table detection (should not flag as deprecated) Co-Authored-By: Claude <noreply@anthropic.com> * test: add integration test for commit-generation deprecation warning Add test that exercises the full deprecation path through check_and_migrate() for commit-generation section rename and args merge. This improves coverage on the warning output and migration file generation paths. Co-Authored-By: Claude <noreply@anthropic.com> * test: add integration test for project-level commit-generation deprecation Add test that exercises the project_keys iteration path in check_and_migrate() for project-level commit-generation deprecation warnings. This covers the warning message format that includes project identifiers. Co-Authored-By: Claude <noreply@anthropic.com> * test: add edge case tests for merge_args_into_command Cover the early-return paths in merge_args_into_command(): - Args without command: args preserved (no command to merge into) - Non-string command: args preserved (can't merge into non-string) - Command-only: clean migration without args field These tests exercise the !can_merge validation path. Co-Authored-By: Claude <noreply@anthropic.com> * test: cover malformed config fallback branches in migration Add tests for the `_ => None` fallback branches that handle unusual cases where commit-generation is neither a table nor inline table (e.g., a string value like `commit-generation = "not a table"`). These tests exercise lines 264 and 305 in deprecation.rs. Co-Authored-By: Claude <noreply@anthropic.com> * test: add coverage for edge cases in deprecation migration Add unit tests for: - Empty command with args: args become the command when command="" - Invalid TOML parsing: returns content unchanged - Deduplication path: second call with same path hits early return These tests cover previously uncovered code paths in deprecation.rs. Co-Authored-By: Claude <noreply@anthropic.com> * test: add unit tests for llm helper functions Add tests for format_reproduction_command and is_lock_file to improve code coverage. Co-Authored-By: Claude <noreply@anthropic.com> * test: add unit tests for config merge logic Add tests for: - CommitConfig merge when only base/override has generation - CommitConfig merge when both have generation - CommitGenerationConfig merge for squash_template fields These cover previously uncovered branches in the Merge implementations. Co-Authored-By: Claude <noreply@anthropic.com> * test: add validation tests for new commit.generation format Add tests for validation error paths in the new [commit.generation] config format (both top-level and per-project). Co-Authored-By: Claude <noreply@anthropic.com> * test: add save_to() tests for commit.generation serialization Cover the "create from scratch" branch in save_to() which serializes commit.generation and deprecated commit-generation sections to new files. Previously only the "update existing file" branch was tested. Co-Authored-By: Claude <noreply@anthropic.com> * docs: fix "Claude CLI" to "Claude Code" Co-Authored-By: Claude <noreply@anthropic.com> * docs: deduplicate LLM setup from config page Remove Claude Code/llm setup examples from config docs since they duplicate llm-commits.md. Config page now links to llm-commits.md for setup and keeps only the custom prompt templates section. Co-Authored-By: Claude <noreply@anthropic.com> * fix: trigger deprecation warnings in `wt config show` Previously `config show` read files directly without calling the config loaders, so deprecation warnings weren't shown. Now we call UserConfig::load() and repo.load_project_config() to trigger warnings while still displaying invalid configs (the deprecation check runs on raw content before parsing). Co-Authored-By: Claude <noreply@anthropic.com> * docs: move aichat into Setup section with other options Move aichat example from "Alternative tools" into the Setup section as "Option 3: aichat" alongside Claude CLI and llm. Add "Custom scripts" subsection for the generic example. Remove the now-redundant "Alternative tools" section. Co-Authored-By: Claude <noreply@anthropic.com> * docs: reframe LLM setup as examples, not numbered options Change from "Option 1/2/3" to just showing examples of tools that work. Lead with the concept: any command that reads stdin and outputs a commit message. Simplify Claude Code example and condense install instructions. Co-Authored-By: Claude <noreply@anthropic.com> * Simplify LLM commit generation setup documentation Remove redundant setup instructions and tool-specific examples from config templates and documentation. Consolidate guidance to reference the main LLM commits docs page for setup details. * Skip deprecated section key in unknown fields warning Skip the "commit-generation" key when warning about unknown fields, since it's already handled by the deprecated sections warning and this prevents duplicate warnings in config output. * Extract DEPRECATED_SECTION_KEYS constant for reuse Instead of hardcoding "commit-generation" in the skip check, define a constant that documents which section keys are deprecated. This makes it easier to add future deprecated sections without forgetting to update the skip logic. Co-Authored-By: Claude <noreply@anthropic.com> * Remove unused has_args field from CommitGenerationDeprecations The has_args field was tracked but never used in production code — the migration logic runs unconditionally and handles both cases (with or without args). This simplifies the struct and removes a redundant test. Co-Authored-By: Claude <noreply@anthropic.com> * Move deprecated section filtering to callers of warn_unknown_fields Instead of having warn_unknown_fields know about deprecated sections and skip them internally, make the constant public and have callers filter before calling. This is cleaner because: 1. warn_unknown_fields doesn't need to know about the deprecation system 2. Callers already interact with deprecation, so filtering there is natural 3. The coupling is explicit rather than hidden inside the function Co-Authored-By: Claude <noreply@anthropic.com> * fix: use Unix shell escaping for migration hint command The `mv` command in the migration hint is a Unix command, so use `shell_escape::unix::escape` instead of the platform-specific `escape` to get consistent output on all platforms. Co-Authored-By: Claude <noreply@anthropic.com> * fix: normalize path separators before shell escaping Convert backslashes to forward slashes before shell escaping so the migration hint command is consistent across platforms. Forward slashes work in Git Bash on Windows. Co-Authored-By: Claude <noreply@anthropic.com> * fix: remove shell escaping from migration hint paths Shell escaping was producing different output on Windows vs Unix even with unix::escape, likely due to some invisible path characteristic. Since config paths rarely contain special characters, just output the paths directly with forward slashes. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> |
||
|
|
41b241162b |
feat: add per-project config overrides (#749)
* feat: add worktree-path support to per-project user config
Allow users to specify different worktree path templates for different
projects in their user config, enabling portable dotfiles across
machines with different project structures.
Config format:
```toml
[projects."github.com/user/repo"]
worktree-path = ".worktrees/{{ branch | sanitize }}"
approved-commands = ["npm ci"]
```
Per-project worktree-path takes precedence over global, which falls
back to the default template.
Closes #596
Co-Authored-By: Claude <noreply@anthropic.com>
* feat: add per-project config for commit-generation, list, commit, and merge
Extend the per-project user config to support overriding more settings:
- [projects."...".commit-generation] - LLM model, args, template
- [projects."...".list] - branches, remotes, full defaults
- [projects."...".commit] - stage mode
- [projects."...".merge] - squash, commit, rebase, remove, verify
Config precedence: CLI arg > project config > global config > default
Implementation:
- Add Merge trait for field-wise config merging (other takes precedence)
- Add effective_* methods to WorktrunkConfig for merged config access
- Add helper methods on CommandEnv/CommandContext for easy access
- Update all commands to use effective configs instead of direct access
- Fix approval clearing to preserve other per-project settings
The approval clearing fix prevents data loss: previously clearing approvals
would wipe all per-project settings (worktree-path, commit-generation, etc).
Now it only clears approved-commands and removes project entries only if
completely empty.
Co-Authored-By: Claude <noreply@anthropic.com>
* refactor: extract merge_optional helper to reduce duplication
DRY improvement: the effective_list, effective_commit, and effective_merge
methods all had identical 4-way match logic. Extract to a generic helper
function that handles the merge pattern.
Co-Authored-By: Claude <noreply@anthropic.com>
* docs: simplify per-project config documentation
- Clarify that per-project settings contain approvals + optional overrides
- Put approved-commands first (primary use case)
- Use TOML dotted keys for compact examples (list.full, merge.squash)
- Remove verbose examples that repeated the section header
Co-Authored-By: Claude <noreply@anthropic.com>
* refactor: drop `effective_` prefix from config accessor methods
The `project: Option<&str>` parameter already indicates merging behavior.
Renamed methods:
- WorktrunkConfig: commit_generation(), list(), commit(), merge()
- CommandEnv/CommandContext: commit_generation(), commit(), merge()
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: escape brackets in doc comments to avoid rustdoc link errors
Rustdoc interprets `[text]` as intra-doc links. Use backticks to make
them code spans instead.
Co-Authored-By: Claude <noreply@anthropic.com>
* test: update help snapshots after merge
Updated config help snapshots to reflect per-project config documentation.
Co-Authored-By: Claude <noreply@anthropic.com>
* test: add validation tests for config edge cases
Add tests for config validation:
- Empty worktree-path (global and per-project)
- Absolute worktree-path (global and per-project)
- Mutual exclusivity of template/template-file options
Extracted validation into a separate `validate()` method to avoid
code duplication between `load()` and test helper.
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: use platform-appropriate absolute paths in validation tests
On Windows, `/absolute/path` is not considered absolute - Windows uses
`C:\path` style. Use cfg!(windows) to conditionally set the test path.
Co-Authored-By: Claude <noreply@anthropic.com>
* docs: fix project_id() doc comments to describe path fallback
The doc comments incorrectly stated that project_id() returns None when
there's no remote URL. The actual implementation falls back to the
canonical repository path, only returning None for non-UTF-8 paths.
Co-Authored-By: Claude <noreply@anthropic.com>
* feat: mark per-project setting overrides as experimental
- Add "(Experimental)" to per-project settings section heading
- Clarify that setting overrides (worktree-path, list, commit, merge) are
new while approved-commands is stable
- Replace manual PartialEq impl with derive for CommitGenerationConfig
Co-Authored-By: Claude <noreply@anthropic.com>
* refactor: minor code simplifications
- Replace .to_string().as_str() with &.to_string()
- Replace .is_some() + .unwrap() with tuple pattern match
Co-Authored-By: Claude <noreply@anthropic.com>
* refactor: fix if-let formatting
Move opening brace to same line as if-let condition to match code style.
---------
Co-authored-by: Claude <noreply@anthropic.com>
|
||
|
|
bada0d298d |
fix: convert bare URLs to proper markdown links in docs (#664)
Replace angle-bracket URLs (<https://...>) with proper markdown links that render nicely on web while showing descriptive text in CLI help. - src/cli/mod.rs: Use Zola @/ syntax for internal links - dev/config.example.toml: Remove angle brackets (plain URLs for TOML) - .claude-plugin/CLAUDE.md: Use GitHub shorthand for issue link CLI now shows "LLM commits docs" and "`wt hook` docs" instead of raw URLs. Web docs render as clickable links with descriptive text. Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
93acd3531c |
Restore visual hierarchy for help headers (#638)
* style: improve help hierarchy and add visible dividers - Render `---` as visible dimmed line (────────────────) instead of blank - Restructure user config: promote "LLM commit messages" to H2 - Group command defaults under "Command defaults" H2 with H3 subsections - Remove "defaults" from titles: "List command defaults" → "List" - Convert "Commit template"/"Squash template" to bold text (parent is now H3) Co-Authored-By: Claude <noreply@anthropic.com> * docs: add TODO explaining H1/divider tradeoff Document why we use `---` dividers instead of H1 headers and list alternative approaches considered. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
46827d2d4e | feat: restore visual hierarchy and add section dividers | ||
|
|
20a5b97546 |
style: use sentence case for CLI help headings (#620)
* Refactor config documentation into single source file - Create `dev/config.source.md` as canonical markdown source for user config documentation - Extract config content from CLI help text into sourced file via `include_str!` - Generate `dev/config.example.toml` from source by commenting all lines - Sync default LLM templates between `src/llm.rs` and source markdown - Update help snapshots to reflect restructured content - Simplify test logic: split template sync into separate source test - Remove manual template commenting logic in favor of transform function * refactor: move user config docs from dev/config.source.md into cli/mod.rs The user config documentation is now embedded directly in src/cli/mod.rs between USER_CONFIG_START/END markers, eliminating the separate markdown file. The sync tests extract this section for transforming to dev/config.example.toml. Co-Authored-By: Claude <noreply@anthropic.com> * Refactor config documentation formatting Reorganize and clarify configuration documentation across multiple files by improving readability of location information, worktree path examples, template variable descriptions, and removing obsolete template-file configuration options. * refactor: inline user config docs into CLI help Move user config documentation from separate `dev/config.source.md` into `src/cli/mod.rs` using marker comments. This makes the CLI the single source of truth for config documentation. Changes: - Add USER_CONFIG_START/END markers in mod.rs for content extraction - Update readme_sync.rs to extract from mod.rs instead of separate file - Delete dev/config.source.md (content now inline) - Remove `wt config create` subdoc expansion (redundant with main help) - Restore User Hooks section and approvals management tip - Reorganize help: Examples first, then Configuration files table - Fix various formatting issues (lists, line wrapping, TOML comments) - Remove obsolete template-file documentation (feature removed) Co-Authored-By: Claude <noreply@anthropic.com> * style: use sentence case for CLI help headings Standardize all help text headings to sentence case (only first word capitalized, except for proper nouns and acronyms like CLI, JSON, LLM). This follows common CLI conventions (git, cargo) where headings read more naturally as prose. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
fe12a688fb |
refactor: inline user config docs into CLI help (#618)
* Refactor config documentation into single source file - Create `dev/config.source.md` as canonical markdown source for user config documentation - Extract config content from CLI help text into sourced file via `include_str!` - Generate `dev/config.example.toml` from source by commenting all lines - Sync default LLM templates between `src/llm.rs` and source markdown - Update help snapshots to reflect restructured content - Simplify test logic: split template sync into separate source test - Remove manual template commenting logic in favor of transform function * refactor: move user config docs from dev/config.source.md into cli/mod.rs The user config documentation is now embedded directly in src/cli/mod.rs between USER_CONFIG_START/END markers, eliminating the separate markdown file. The sync tests extract this section for transforming to dev/config.example.toml. Co-Authored-By: Claude <noreply@anthropic.com> * Refactor config documentation formatting Reorganize and clarify configuration documentation across multiple files by improving readability of location information, worktree path examples, template variable descriptions, and removing obsolete template-file configuration options. * refactor: inline user config docs into CLI help Move user config documentation from separate `dev/config.source.md` into `src/cli/mod.rs` using marker comments. This makes the CLI the single source of truth for config documentation. Changes: - Add USER_CONFIG_START/END markers in mod.rs for content extraction - Update readme_sync.rs to extract from mod.rs instead of separate file - Delete dev/config.source.md (content now inline) - Remove `wt config create` subdoc expansion (redundant with main help) - Restore User Hooks section and approvals management tip - Reorganize help: Examples first, then Configuration files table - Fix various formatting issues (lists, line wrapping, TOML comments) - Remove obsolete template-file documentation (feature removed) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
a9ed5344ed |
refactor: rename main_worktree_path template var to primary_worktree_path (#613)
* refactor: rename main_worktree_path template var to primary_worktree_path The old name was confusing because "main worktree" has a specific meaning in git (the original clone directory), but the template variable actually provided the "primary" worktree — where established files live. - Rename template var: main_worktree_path → primary_worktree_path - Remove default_branch_worktree() method, inline into primary_worktree() - Add deprecation mapping so existing configs continue to work - Update all documentation and examples Co-Authored-By: Claude <noreply@anthropic.com> * docs: improve primary_worktree_path description in examples Update the template variable description from "Where established files live" to "Main worktree (or default branch worktree for bare repos)" for clarity. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
e551c4d333 |
feat(list): add experimental per-task timeout config (#601)
* feat(list): add experimental per-task timeout config Add configurable timeout for `wt list` git operations via `[list] timeout-ms` in user config. - Replace `timed_out: bool` with `ErrorCause` enum for extensibility - Show timeout count in footer: "3 tasks timed out (run with `-v` for details)" - `0` means no timeout (explicit disable) - `--full` always disables timeout for complete data collection - Add comprehensive unit and integration tests Co-Authored-By: Claude <noreply@anthropic.com> * Address Codex review feedback for timeout feature - Make `cause` field private, access via `is_timeout()` method - Fix SHA slicing with safe `sha[..sha.len().min(8)]` - Update "killed gracefully" to "terminated" in docs - Add timeout-ms = 0 to config defaults - Single constructor for TaskError (takes cause parameter) - Show all errors in footer with timeout breakout: - "3 tasks timed out" (all timeouts) - "5 tasks failed (3 timed out)" (mixed) - "2 tasks failed" (no timeouts) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
6a4aa35e7e |
docs: consolidate template variables reference into hook.md (#544)
- Remove deprecated variable mentions from all docs - Replace duplicate table in step.md with link to hook.md#template-variables - Add URL to canonical reference in project config template - All filters (sanitize, sanitize_db, hash_port) documented in hook.md Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
56c26f289d |
refactor: replace dev scripts with Taskfile (#542)
Consolidate 7 shell scripts into a single Taskfile.yml using go-task: - coverage: run tests with coverage - setup-web: setup Claude Code web environment - fetch-assets: download assets from worktrunk-assets - publish-assets: publish assets to worktrunk-assets - build-social-cards: generate social card PNGs - generate-logo: generate logo with Gemini AI Remove update-homebrew task (now handled by CI workflow). Update CLAUDE.md files to reference `task X` commands and add task runner installation instructions for web environments. Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
75c39245d9 |
refactor: simplify dev/coverage.sh (#541)
Reduce from 38 lines to 2. Removed: - Toolchain workaround (rust-toolchain.toml handles this) - llvm-tools component check (cargo-llvm-cov handles this) - LCOV generation (CI uses cobertura, not LCOV) - Separate no-report + report passes (--html does both) Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
bf575aaaee |
Redesign social cards with horizontal layout (#522)
* Redesign social cards with horizontal layout - New horizontal layout: logo left, text right - Warm radial glow emanating from logo - Refined typography: 88px title with tight tracking, 28px tagline - Darker title color (#1a1817) for better hierarchy - Move generated PNGs to assets repo (same pattern as demos) - Add build script with automatic font downloading Co-Authored-By: Claude <noreply@anthropic.com> * Fix deploy workflow to include social cards The assets repo now has both demos/ and social/ directories. Co-Authored-By: Claude <noreply@anthropic.com> * Simplify assets structure: single path copy Restructured worktrunk-assets repo to have all content under assets/ so deploy workflow can use a single `cp -r` command. Co-Authored-By: Claude <noreply@anthropic.com> * Address review feedback - Fix typo: "ONGs" → "PNGs" - Fix stale comment: "Google Fonts" → "GitHub releases" - Add -f flag to curl for better error handling - Document purpose of each social card size Co-Authored-By: Claude <noreply@anthropic.com> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix asset URL in README for restructured repo The worktrunk-assets repo was restructured from demos/ to assets/. Update the URL transform in readme_sync.rs to match. Co-Authored-By: Claude <noreply@anthropic.com> * Fix README demo links after assets repo restructure - Update wt-core.gif URL from demos/ to assets/ path - Add PNGs exception to typos config (was incorrectly flagged) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> |
||
|
|
962b548bbf |
feat: add sanitize_db filter for database-safe identifiers (#498)
* feat: add sanitize_db filter for database-safe identifiers Add a new template filter `sanitize_db` that transforms strings into database-safe identifiers compatible with PostgreSQL, MySQL, and SQL Server. Transformation rules: - Convert to lowercase - Replace non-alphanumeric characters with underscore - Collapse consecutive underscores - Prefix with underscore if starts with digit - Truncate to 63 characters (PostgreSQL limit) Examples: - feature/auth-oauth2 → feature_auth_oauth2 - 123-bug-fix → _123_bug_fix - UPPERCASE.Branch → uppercase_branch Closes #474 Co-Authored-By: Claude <noreply@anthropic.com> * docs: add sanitize_db mention to database per worktree section Add example showing how to use sanitize_db for branch-based database names in the tips-patterns.md guide. Co-Authored-By: Claude <noreply@anthropic.com> * docs: add sanitize_db to example configs and tips-patterns - Add sanitize_db to filter list in wt.example.toml - Add sanitize_db to variables section in config.example.toml - Add usage example in tips-patterns.md database section Co-Authored-By: Claude <noreply@anthropic.com> * docs: simplify URL template description Remove filter list from URL template description - the example already shows hash_port usage and other filters aren't relevant in this context. Co-Authored-By: Claude <noreply@anthropic.com> * feat(sanitize_db): add 3-char hash suffix for collision/keyword safety Appends a deterministic 3-character base36 hash suffix to sanitize_db output. This ensures: - SQL reserved words are avoided (e.g., `user` → `user_abc`) - Different inputs don't collide (e.g., `a-b` and `a_b` get different suffixes since hash is computed from original input) The suffix uses 46,656 unique values (36^3), providing good uniqueness while keeping identifiers readable. Updated all documentation examples to use sanitize_db for database names (POSTGRES_DB, DATABASE_URL) instead of repo name. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> |