feat(config): per-project .fujimoto.yaml worktree setup - #36
Merged
Conversation
Add an optional, local .fujimoto.yaml in the main clone describing files to copy/link into a worktree and init commands to run when launching a session. - copy/link/init sections, validated with pydantic; glob support; hard links fall back to copy (or use symbolic) across filesystems - applied in the parent process on every worktree connection (new, reconnect, resume): `once` runs on first creation (tracked by a marker), `always` runs every time; init runs with `sh -x` and on_error controls abort vs continue - `fujimoto --create-config` scaffolds a commented template (shipped as a package resource) - config read from the main clone (source root), not the worktree checkout - malformed config is surfaced in a modal dialog when the TUI opens Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an optional, local
.fujimoto.yamlin the main clone that describes how to set up a new worktree: files to copy, files to link, and init commands to run when a session launches. Closes the gap where untracked local files (e.g..env) and per-worktree setup weren't carried into fresh worktrees (#35).What's included
project_config.py), validated with pydantic:copy:— copy files into the worktree (glob patterns supported)link:— hard link (default) ortype: symbolic; hard links fall back to a copy + warning across filesystemsinit:— shell commands run withsh -x(visible trace),{{ source_dir }}/{{ worktree_dir }}placeholders, per-commandcontinue_on_erroron_error: abort | continue— what to do when a non-continue_on_errorinit command failswhen: once | alwaysonce→ only the first time the worktree is created (tracked by a.fujimoto/config_once_appliedmarker)always→ every connection.git/info/exclude).fujimoto --create-config— scaffolds a fully commented template (shipped as a package resource)..fujimoto.yamlis surfaced in a modal dialog when the TUI opens (non-blocking; you can still launch a session to fix it). Error text is rendered without markup parsing so pydantic's bracketed messages don't crash the UI.Flow
flowchart TD A["Select / create worktree session in TUI"] --> B["main loop: apply config before attach"] B --> C{"linked worktree?"} C -- no --> L["launch / attach session"] C -- yes --> D["read .fujimoto.yaml from main clone"] D --> V{"config parses?"} V -- no --> L V -- yes --> E{"first creation? (no once-marker)"} E -- yes --> F["trigger = CREATE (once + always)"] E -- no --> G["trigger = LAUNCH (always only)"] F --> H["apply copy / link / init"] G --> H H --> I{"init command failed?"} I -- no --> M["mark once-applied (if first creation)"] I -- yes --> P["print error + pause for keypress"] P --> Q{"on_error = abort?"} Q -- yes --> J["reopen TUI, do not launch"] Q -- no --> M M --> L J --> ASupporting changes
config.py:store_session_metarecordssource_root;config_once_applied/mark_config_once_appliedmarker helpers.git.py:get_main_worktree_root(derives the main clone from a linked worktree).pyyaml,pydantic.--create-config), CLAUDE.md (architecture, design decisions,.venv/uvgotcha), CONTRIBUTING (layout).Tests
New
tests/test_project_config.pyplus additions totest_cli.py/test_config.py/test_git.py. Full suite 452 passing;project_config.pyandconfig.pyat 100% line coverage.No database/schema changes.