Skip to content

Remove Strategy interface abstraction and add commit_linking setting#531

Merged
evisdren merged 9 commits intomainfrom
updateCLIStrategies
Feb 27, 2026
Merged

Remove Strategy interface abstraction and add commit_linking setting#531
evisdren merged 9 commits intomainfrom
updateCLIStrategies

Conversation

@evisdren
Copy link
Contributor

@evisdren evisdren commented Feb 26, 2026

Summary

  • Removes the Strategy interface (~140 lines) that only had one implementation (ManualCommitStrategy), inlining the concrete type throughout the codebase
  • Adds [Y/n/a] to the commit linking prompt so users can opt into auto-linking at commit time
  • When a user picks a (always), the preference is saved to settings.local.json — future commits auto-link without prompting
  • All users default to "prompt" behavior (via GetCommitLinking() returning "prompt" when unset). Users discover "always" through the prompt itself, eliminating setup-time complexity
  • Removes isFirstSetup detection, migrateProjectSettings(), and duplicated save blocks from setup.go

Migration behavior

User type Behavior
New user Sees [Y/n/a] on first commit with active session, can pick a to auto-link
Existing user (no commit_linking set) Same prompt, now with a option
User who already has commit_linking: "always" Auto-links without prompt (unchanged)
User who picks a at prompt settings.local.json gets commit_linking: "always", future commits auto-link

Test plan

  • mise run fmt passes
  • mise run lint passes (0 issues)
  • mise run test:ci passes (all unit + integration tests)
  • Manual: fresh entire enable → no commit_linking in settings (clean)
  • Manual: git commit -m "test" with active session → prompt shows [Y/n/a]
  • Manual: press a → commit links, settings.local.json now has commit_linking: "always"
  • Manual: next git commit -m "test" → auto-links without prompt

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings February 26, 2026 21:57
@evisdren evisdren requested a review from a team as a code owner February 26, 2026 21:57
@cursor
Copy link

cursor bot commented Feb 26, 2026

PR Summary

Medium Risk
Touches git hook behavior and settings parsing/merging, which can affect commit message modification and user workflows if the new commit_linking option is misread or persisted incorrectly. Changes are mostly mechanical type inlining but spread across multiple commands and hooks.

Overview
Simplifies strategy plumbing by removing the Strategy interface and switching call sites to use *strategy.ManualCommitStrategy directly (including GetStrategy, hook contexts, and reset/rewind helpers), with logging now using the manual-commit constant rather than Strategy.Name().

Adds commit_linking to settings ("prompt" default; "always" supported) with validation and local override merge behavior, and updates prepare-commit-msg to optionally auto-link commits or prompt via TTY with a new Always choice that persists commit_linking="always" to settings.local.json.

Removes deprecated strategy field warning output and associated tests, and updates strategy/tests to match the concrete-type API changes.

Written by Cursor Bugbot for commit 6096b8d. Configure here.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request simplifies the codebase architecture by removing an unnecessary abstraction layer and adds a new user-configurable setting for commit linking behavior.

Changes:

  • Removed the Strategy interface abstraction since only ManualCommitStrategy ever existed, replacing all interface references with the concrete type
  • Added a commit_linking setting ("always"/"prompt") to control whether commits are automatically linked to agent sessions or prompt the user each time
  • Set new users to default to "always" (auto-link) while existing users retain "prompt" behavior for backward compatibility
  • Removed deprecated strategy field warnings from status and doctor commands

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
cmd/entire/cli/strategy/strategy.go Removed 146-line Strategy interface definition and all its method signatures
cmd/entire/cli/strategy/manual_commit.go Changed NewManualCommitStrategy to return concrete type, removed Name/Description methods and interface check
cmd/entire/cli/strategy/manual_commit_hooks.go Integrated commit_linking setting into PrepareCommitMsg to control auto-linking vs prompting behavior, added nolint comments
cmd/entire/cli/strategy/manual_commit_logs.go Added nolint comment to suppress false positive unparam warning
cmd/entire/cli/strategy/session_test.go Updated test name and implementation to reflect concrete type usage
cmd/entire/cli/strategy/manual_commit_test.go Removed unnecessary type casting since NewManualCommitStrategy returns concrete type
cmd/entire/cli/settings/settings.go Added CommitLinking field, constants, and GetCommitLinking() method; removed deprecated strategy warning functions
cmd/entire/cli/settings/settings_test.go Added tests for commit_linking field loading, merging, and default behavior; removed deprecated strategy tests
cmd/entire/cli/config.go Changed GetStrategy return type from interface to concrete type
cmd/entire/cli/setup.go Set commit_linking to "always" for new installations in both interactive and non-interactive modes
cmd/entire/cli/status.go Removed calls to WriteDeprecatedStrategyWarnings
cmd/entire/cli/status_test.go Removed tests for deprecated strategy warnings
cmd/entire/cli/doctor.go Removed deprecated strategy warning display from sessions fix command
cmd/entire/cli/doctor_test.go Removed test for deprecated strategy warnings and cleaned up unused imports
cmd/entire/cli/rewind.go Updated function signatures to accept concrete type instead of interface
cmd/entire/cli/reset.go Updated function signature to accept concrete type instead of interface
cmd/entire/cli/hooks_git_cmd.go Removed strategyName field from gitHookContext, use constant directly for logging
cmd/entire/cli/hook_registry.go Use strategy.StrategyNameManualCommit constant directly instead of calling strategy.Name()
cmd/entire/cli/explain_test.go Updated test name and implementation to reflect concrete type usage
cmd/entire/cli/checkpoint/temporary.go Removed nolint:wrapcheck comment (minor/unrelated cleanup)
Comments suppressed due to low confidence (1)

cmd/entire/cli/checkpoint/temporary.go:541

  • This lint comment removal appears unrelated to the PR's purpose of removing the Strategy interface and adding commit_linking. The original comment "Propagating context cancellation" was actually correct - context errors should typically be propagated without wrapping to preserve their semantic meaning for context.Canceled and context.DeadlineExceeded checks.

This change should either be reverted or explained in the PR description if it's intentional cleanup.

				return nil, branchErr

return fmt.Errorf("parsing commit_linking field: %w", err)
}
if cl != "" {
settings.CommitLinking = cl
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

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

The commit_linking field accepts any string value without validation. Invalid values like "never", "sometimes", or typos like "allways" will be silently accepted and treated as "prompt" by GetCommitLinking(), which could lead to unexpected behavior.

Consider adding validation to reject invalid values and provide clear error messages. For example, after unmarshaling the value, check if it's one of the allowed constants (CommitLinkingAlways or CommitLinkingPrompt) and return an error if not.

Suggested change
settings.CommitLinking = cl
switch cl {
case "always", "prompt":
settings.CommitLinking = cl
default:
return fmt.Errorf("invalid commit_linking value %q: must be \"always\" or \"prompt\"", cl)
}

Copilot uses AI. Check for mistakes.
@evisdren
Copy link
Contributor Author

bugbot run

@evisdren evisdren force-pushed the updateCLIStrategies branch from cc555bc to d012bfd Compare February 26, 2026 23:22
@khaong
Copy link
Contributor

khaong commented Feb 27, 2026

Two thoughts on the commit_linking approach:

  1. I remember we discussed having an "always" option on the commit prompt itself — did that get dropped for a reason? A [Y/n/a] where a writes commit_linking: "always" to settings.local.json feels like the natural place for this. Users discover it when they're actually committing, and since it's a personal preference (one dev likes prompts, another doesn't), local settings is the right home.

  2. If we go that route, commit_linking can just be a normal setting — no need for migrateProjectSettings, the struct-copy-and-strip, or the duplicated save blocks. determineSettingsTarget and settings.Load() already handle the merge.

@evisdren
Copy link
Contributor Author

Two thoughts on the commit_linking approach:

  1. I remember we discussed having an "always" option on the commit prompt itself — did that get dropped for a reason? A [Y/n/a] where a writes commit_linking: "always" to settings.local.json feels like the natural place for this. Users discover it when they're actually committing, and since it's a personal preference (one dev likes prompts, another doesn't), local settings is the right home.
  2. If we go that route, commit_linking can just be a normal setting — no need for migrateProjectSettings, the struct-copy-and-strip, or the duplicated save blocks. determineSettingsTarget and settings.Load() already handle the merge.
  1. Yes, you're right. Will add that in.
  2. Good point, will update

@evisdren evisdren force-pushed the updateCLIStrategies branch from 236eafe to 5f88e29 Compare February 27, 2026 05:17
@evisdren
Copy link
Contributor Author

bugbot run

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Comment @cursor review or bugbot run to trigger another review on this PR

}

// Helper to save settings to the appropriate file
// Save settings to the appropriate file.
Copy link

Choose a reason for hiding this comment

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

New users never get "always" commit linking default

High Severity

The PR description states new users (via entire enable) should default to commit_linking: "always" (auto-link), while existing users without the setting default to "prompt". However, neither runEnableInteractive nor setupAgentHooksNonInteractive ever sets CommitLinking on the settings object. Since GetCommitLinking() returns CommitLinkingPrompt when the field is empty, all users — including new ones — get "prompt" behavior instead of the intended "always".

Additional Locations (1)

Fix in Cursor Fix in Web

Copy link
Contributor Author

Choose a reason for hiding this comment

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

this was based on outdataed PR description - resolved now

return fmt.Errorf("saving local settings: %w", err)
}
return nil
}
Copy link

Choose a reason for hiding this comment

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

Saving commit linking creates unintended enabled override

Medium Severity

saveCommitLinkingAlways calls settings.LoadFromFile on a potentially nonexistent settings.local.json, which returns a default struct with Enabled: true. It then saves the full struct, writing "enabled": true into local settings as a side effect. This pins an explicit enabled: true in the local file that wasn't user-intended, which could prevent a later project-level enabled: false from taking effect since local settings override project settings during merge.

Fix in Cursor Fix in Web

@evisdren
Copy link
Contributor Author

cursor bugbot

evisdren and others added 9 commits February 26, 2026 21:52
The CLI had a Strategy interface designed for multiple implementations,
but only ManualCommitStrategy ever existed. This removes the interface
and inlines the concrete type, reducing indirection. Also adds a
commit_linking setting ("always"/"prompt") so new users get auto-linked
commits by default while existing users keep the interactive prompt.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Entire-Checkpoint: 91746634036b
… behavior

- Validate commit_linking values in loadFromFile() and mergeJSON() to reject
  typos/invalid values (Copilot feedback)
- Only set commit_linking="always" for first-time installations, not when
  existing users re-run "entire enable" (Cursor feedback)
- Applied fix to both setup paths (interactive and non-interactive)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Entire-Checkpoint: 6eed77bbdf5a
…oded string

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Entire-Checkpoint: 23022eee7a62
When existing users re-run "entire enable", clear the deprecated strategy
field and explicitly write commit_linking: "prompt" so the settings file
reflects the current spec.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Entire-Checkpoint: 7cb76929faa3
…gy field

When "entire enable" routes saves to settings.local.json (because
settings.json already exists), the project file was left with the stale
"strategy" field. Now migrateProjectSettings() loads settings.json
directly, clears the deprecated strategy field, writes commit_linking
if missing, and saves it back.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Entire-Checkpoint: 64597ed00591
…rce of truth

When "entire enable" routes to settings.local.json, the commit_linking
field was being written there too. This meant editing settings.json to
change commit_linking had no effect because the local file's value
always won on merge. Now commit_linking is only written to settings.json
(via migrateProjectSettings), and the local file omits it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Entire-Checkpoint: 0a2fd94192c1
Replace complex setup-time commit_linking logic (isFirstSetup detection,
migrateProjectSettings, struct-copy-and-strip) with a simpler UX: users
discover commit_linking="always" through the commit prompt itself. When
they pick "a", the preference is saved to settings.local.json.

- Add ttyConfirmResult type with Yes/No/Always to askConfirmTTY
- Add saveCommitLinkingAlways helper for persisting the preference
- Update PrepareCommitMsg to handle three-way prompt result
- Remove isFirstSetup checks, commit_linking init blocks, and
  migrateProjectSettings from setup.go
- Remove unused CommitLinkingAlways/CommitLinkingPrompt aliases from config.go

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Entire-Checkpoint: 9da9b16fff31
…riptions

Restructure askConfirmTTY to display a header, indented details, and
self-documenting options ([Y]es / [n]o / [a]lways) so users understand
what each choice does without guessing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Entire-Checkpoint: 74991c8b8e1b
…settings

Use raw JSON merge instead of LoadFromFile+SaveLocal to set only the
commit_linking field. LoadFromFile returns Enabled:true by default, which
would pin an explicit override in settings.local.json that prevents a
later project-level enabled:false from taking effect.

Also updated PR description to reflect that all users default to "prompt"
behavior — users discover "always" through the [Y/n/a] commit prompt,
not through setup-time logic.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Entire-Checkpoint: 4bffc26b6ff1
@evisdren evisdren force-pushed the updateCLIStrategies branch from 1e42f15 to 09c7882 Compare February 27, 2026 05:52
@evisdren evisdren merged commit 787921f into main Feb 27, 2026
3 checks passed
@evisdren evisdren deleted the updateCLIStrategies branch February 27, 2026 06:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants