Introduce skul reset (de-materialize worktree)#6
Merged
Conversation
skul clean --bundle <name> removes only the named bundle's managed files from the current worktree, leaving other bundles intact. The git exclude block is updated accordingly (or removed if the last bundle is cleaned). Desired state is not modified, matching the clean-vs-remove distinction. https://claude.ai/code/session_01QZw8LYCJATVjcgAgSMnrWB
- Distinguish unknown bundle (throws) from unmaterialized bundle (soft
message) by checking desired_state before returning early
- Fix options shape: no longer stores { bundle: undefined } when
--bundle is omitted; now stores {} to match the type accurately
- Add missing tests: clean --bundle outside a Git repo, clean --bundle
on a bundle in desired state but not materialized in the current
worktree (linked-worktree case), throws on unknown bundle name, and
cleans all tools for a multi-tool bundle
https://claude.ai/code/session_01QZw8LYCJATVjcgAgSMnrWB
skul clean was confusing because "clean" reads like a build-tool artifact removal rather than a worktree de-materialization. reset better expresses that it is the inverse of apply. Also remove the --bundle flag introduced in the previous two commits. The distinction between remove (forgets intent) and clean --bundle (de-materializes without forgetting) was too subtle and had no compelling use case that add/remove don't already cover. Final command surface: add / remove / apply / reset / status / list. https://claude.ai/code/session_01QZw8LYCJATVjcgAgSMnrWB
The PromptClient interface, its implementation in createPromptClient, and the confirmManagedFileRemovals private function still declared "clean" as a valid operation literal after the rename. The implementation was already passing "reset", so this was a type/message mismatch rather than a runtime failure, but the user-facing prompt message also read "during clean" instead of "during reset". https://claude.ai/code/session_01QZw8LYCJATVjcgAgSMnrWB
- Rename stale test description 'cleans all' -> 'resets all' - Give reset its own command registration with a real description instead of sharing the 'Placeholder command' loop with list/status - Update TASKS.md: rename skul clean -> skul reset on line 18, mark remove and reset as DONE, drop the superseded clean --bundle entry, update handoff note to reflect current priorities - Fix multi-bundle reset atomicity: collect all user confirmations before removing any files so a decline on bundle N does not leave bundles 0..N-1 deleted while the registry still records them https://claude.ai/code/session_01QZw8LYCJATVjcgAgSMnrWB
sjquant
pushed a commit
that referenced
this pull request
May 19, 2026
- Extract buildGlobalRepoRelPathRemapper() in tool-mapping.ts so the CLAUDE.md → .claude/CLAUDE.md mapping is derived from GLOBAL_TOOL_DEFINITIONS rather than hardcoded in two call sites. - Remove redundant requestedTools/selectedTools dual-derivation in applyBundleGlobal; single selectedTools variable now covers both paths. - Fix applyGlobal double-fetch: remove outer fetchRemoteSource loop and collect clone output directly from applyBundleGlobal return values, so clone lines are not duplicated or silently dropped when multiple bundles are applied. - Drop hardcoded "Home: ~/.claude/" line from renderGlobalStatus; the function receives no homeDir and the string was always wrong for non-default home dirs. - Use cloneMaterializedBundleState in cloneWorktreeState to eliminate the duplicated inline bundle-cloning block (review issue #6). - Add JSDoc notes to getGlobalToolDefinition and resolveGlobalToolTargetPath explaining they are exported for external consumers. - Add 3 integration tests: dry-run remove --global, dry-run reset --global, remove a bundle that is in desired_state but not materialized. https://claude.ai/code/session_01LqY5ib47389veB72TSQmBW
sjquant
pushed a commit
that referenced
this pull request
May 19, 2026
- Extract buildGlobalRepoRelPathRemapper() in tool-mapping.ts so the CLAUDE.md → .claude/CLAUDE.md mapping is derived from GLOBAL_TOOL_DEFINITIONS rather than hardcoded in two call sites. - Remove redundant requestedTools/selectedTools dual-derivation in applyBundleGlobal; single selectedTools variable now covers both paths. - Fix applyGlobal double-fetch: remove outer fetchRemoteSource loop and collect clone output directly from applyBundleGlobal return values, so clone lines are not duplicated or silently dropped when multiple bundles are applied. - Drop hardcoded "Home: ~/.claude/" line from renderGlobalStatus; the function receives no homeDir and the string was always wrong for non-default home dirs. - Use cloneMaterializedBundleState in cloneWorktreeState to eliminate the duplicated inline bundle-cloning block (review issue #6). - Add JSDoc notes to getGlobalToolDefinition and resolveGlobalToolTargetPath explaining they are exported for external consumers. - Add 3 integration tests: dry-run remove --global, dry-run reset --global, remove a bundle that is in desired_state but not materialized. https://claude.ai/code/session_01LqY5ib47389veB72TSQmBW
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.
What
Adds
skul reset, which removes all Skul-managed files from the current worktree without touching the repository's desired state. It is the inverse of the upcomingskul apply.Final command surface:
Why reset, not clean
cleanreads like a build-tool artifact removal.resetmakes theapply/resetpairing explicit — one materializes, the other de-materializes.Behaviour
.git/info/excludewhen doneskul applyto re-materialize laterChanges
CommandNameandCliParseResultupdated:"clean"→"reset"cleanWorktreerenamed toresetWorktree;--bundleflag dropped (no compelling use case thatremove+adddon't already cover)PromptClientinterface, its implementation, and the internalconfirmManagedFileRemovalshelper updated from"clean"to"reset"literal — fixes a type/message mismatch where the user-visible prompt read "during clean" even after the renameOpen questions for review
resetcould be confused withgit reset(which alters index/HEAD).clean(likegit clean) may be more intuitive. Happy to revert the rename if the team prefersclean.--bundlescope: The spec listed per-bundle scoped de-materialization as a TODO. It was dropped here becauseskul remove+skul addcovers the same ground. If multi-worktree workflows surface a real need for it, it can be re-added on top of this.