Documentation
¶
Index ¶
- Variables
- func AddAllAndCommit(dir, message string, timeoutSeconds int) error
- func AddAndCommitFile(dir, newFilename, message string) error
- func CheckStagedChanges(dir string) error
- func CleanCommitMessage(message string) string
- func CommittedFilePaths(workDir string) (map[string]bool, error)
- func GetFileGitPath(filename string) (string, error)
- func GetGitRemoteURL() (string, error)
- func GetGitRootDir() (string, error)
- func GetGitStatus() (currentBranch string, uncommittedChanges int, stagedChanges int, err error)
- func GetRecentFileLog(filePath string, limit int) (string, error)
- func GetRecentTouchedFiles(numCommits int) ([]string, error)
- func GetStagedChanges() (string, error)
- func GetStagedDiff(dir string) (string, error)
- func GetUncommittedChanges() (string, error)
- func IsFileContentCommitted(filePath string) (bool, error)
- func NormalizeShortTitle(raw string) string
- func ParseCommitMessage(commitMessage string) (string, string, error)
- func ParseGitHubRemoteURL(remoteURL string) (owner, repo string, err error)
- func PerformGitCommit(dir, message string) error
- func SafeGitCmd(dir string, args ...string) *exec.Cmd
- func TruncateRunes(s string, max int) string
- func WrapText(text string, lineLength int) string
- type CommitExecutor
- func NewCommitExecutor(client api.ClientInterface, userMessage, userInstructions string) *CommitExecutor
- func NewCommitExecutorInDir(client api.ClientInterface, userMessage, userInstructions, dir string) *CommitExecutor
- func NewCommitExecutorWithSecurityCheck(client api.ClientInterface, userMessage, userInstructions string, ...) *CommitExecutor
- type CommitFileChange
- type CommitMessageOptions
- type CommitMessageResult
- type CommitOptions
- type CommitSecurityResult
- type PullRequestRequest
- type PullRequestResult
- type SecretCheckHandler
Constants ¶
This section is empty.
Variables ¶
var ErrNoGitHubAuth = errors.New("no GitHub authentication available")
ErrNoGitHubAuth is the sentinel returned when neither a GH_TOKEN nor the gh CLI are available for PR creation. The wrapped error message contains the exact gh pr create command the user can run manually.
var GetDefaultBranch = func(ctx context.Context, repoDir string) (string, error) { cmd := exec.CommandContext(ctx, "git", "symbolic-ref", "--short", "refs/remotes/origin/HEAD") cmd.Dir = repoDir out, err := cmd.Output() if err != nil { return "main", nil } return strings.TrimSpace(string(out)), nil }
GetDefaultBranch returns the default branch name for the repo rooted at repoDir. By default it reads
git symbolic-ref refs/remotes/origin/HEAD
and falls back to "main". Tests may override this variable.
var GitHubAPIBaseURL = "https://api.github.com"
GitHubAPIBaseURL is the base URL for the GitHub REST API. Tests may override it to point at an httptest server.
var PushBranch = func(ctx context.Context, repoDir, head string) error { cmd := exec.CommandContext(ctx, "git", "push", "-u", "origin", head) cmd.Dir = repoDir out, err := cmd.CombinedOutput() if err != nil { return fmt.Errorf("push branch %q to origin: %w (output: %s)", head, err, strings.TrimSpace(string(out))) } return nil }
PushBranch executes "git push -u origin <head>". Tests may override this variable to avoid network access.
NOTE: intentionally exported only for testability — follow the same pattern as RunGhCommand / GetDefaultBranch. Not safe for concurrent writes; override in init() or TestMain, not mid-flight.
var RunGhCommand = func(ctx context.Context, dir string, args ...string) ([]byte, error) { cmd := exec.CommandContext(ctx, "gh", args...) cmd.Dir = dir out, err := cmd.CombinedOutput() return out, err }
RunGhCommand is the function used to invoke the gh CLI. The default implementation simply calls exec.CommandContext("gh", args...). Tests may override this variable to avoid a real binary.
NOTE: this variable is intentionally not safe for concurrent writes — override it in init() or TestMain, not mid-flight.
Functions ¶
func AddAllAndCommit ¶
AddAllAndCommit commits all staged changes inside dir with the provided message (non-interactive). dir MUST be non-empty.
func AddAndCommitFile ¶
AddAndCommitFile stages the specified file and commits it with the given message inside dir. dir MUST be non-empty — passing "" would let the operation hit the test process's CWD (the host repo on developer machines) and is refused by SafeGitCmd under `go test`.
func CheckStagedChanges ¶
CheckStagedChanges verifies if there are staged changes in the given directory. If dir is empty, it runs in the process CWD.
func CleanCommitMessage ¶
CleanCommitMessage cleans up LLM-generated commit messages
func CommittedFilePaths ¶ added in v0.16.18
CommittedFilePaths returns a set of absolute filesystem paths for files that are tracked by git AND whose working-tree content is identical to HEAD (committed-clean). This is the batch equivalent of IsFileContentCommitted: instead of two subprocess calls per file, it runs just two commands total (git ls-files + git diff --name-only HEAD) and builds the full set in one pass.
All git commands are run with cmd.Dir=workDir so the function does not depend on the process CWD — it resolves the repo containing workDir regardless of where the agent process is running.
Callers use this to identify working-tree deltas caused by git operations (merge, checkout, reset, pull) that should NOT be recorded as recoverable agent edits — a file whose post-operation content matches HEAD was aligned to a committed state by git, not edited by the agent, so there is nothing legitimate to "recover" back to.
Returns (nil, nil) when workDir is not inside a git repository — no git protection applies and callers should record all deltas.
func GetFileGitPath ¶
GetFileGitPath returns the path of the given filename relative to the Git repository root.
func GetGitRemoteURL ¶
GetGitRemoteURL returns the remote URL of the current Git repository.
func GetGitRootDir ¶
GetGitRootDir returns the absolute path to the root directory of the current Git repository.
func GetGitStatus ¶
GetGitStatus returns the current branch, number of uncommitted changes, and number of staged changes.
func GetRecentFileLog ¶
GetRecentFileLog returns a short summary of recent commits for a file
func GetRecentTouchedFiles ¶
GetRecentTouchedFiles returns a de-duplicated list of files touched in the last N commits
func GetStagedChanges ¶
GetStagedChanges returns detailed information about staged changes in the repository.
func GetStagedDiff ¶
GetStagedDiff returns the diff of staged changes in the given directory. If dir is empty, it runs in the process CWD.
func GetUncommittedChanges ¶
GetUncommittedChanges returns detailed information about uncommitted changes in the repository.
func IsFileContentCommitted ¶ added in v0.16.18
IsFileContentCommitted reports whether the working-tree version of filePath matches what is recorded at git HEAD — i.e. the file is tracked by git AND has no uncommitted modifications. This is the git-awareness primitive used by the revert/recover staleness guards to refuse rolling back work that the user has intentionally committed to version control.
Semantics:
- Not a git repo (GetGitRootDir fails) → (false, nil): no git protection applies; callers fall back to the content-only check.
- File not tracked by git (untracked, or HEAD:<path> unknown) → (false, nil): no git protection; content check applies.
- File tracked and working tree matches HEAD → (true, nil): PROTECTED — the content is committed; reverting to an older snapshot would silently undo committed work.
- File tracked but differs from HEAD (uncommitted modifications) → (false, nil): not protected; the content-only staleness check still decides.
The check is performed in two steps:
- `git ls-files --error-unmatch <relpath>` verifies the file is tracked by git. Untracked files exit non-zero.
- `git diff --quiet HEAD -- <relpath>` confirms the working-tree copy is identical to HEAD. Both are read-only commands, so SafeGitCmd is invoked with dir="" (matching the existing GetGitStatus / GetUncommittedChanges pattern), which is not blocked by the test-mode mutating-command guard.
Step 1 is critical: `git diff --quiet HEAD -- <path>` alone returns exit 0 for UNTRACKED files because `git diff` does not include untracked files in its comparison. Without the tracked-file gate, a freshly-created (but never `git add`ed) file would be incorrectly reported as committed-clean, breaking the staleness guard.
Any unexpected git error is returned as (false, err) so callers can fall back to the conservative content-only behavior rather than blocking legitimate reverts.
func NormalizeShortTitle ¶
func ParseCommitMessage ¶
ParseCommitMessage parses a commit message into note and description
func ParseGitHubRemoteURL ¶ added in v0.16.12
ParseGitHubRemoteURL extracts the owner and repository name from a GitHub remote URL. It supports both HTTPS and SSH formats:
https://github.com/owner/repo.git -> owner, repo git@github.com:owner/repo.git -> owner, repo
Returns an error for non-GitHub remotes or unrecognised formats.
func PerformGitCommit ¶
PerformGitCommit executes the git commit command safely using stdin inside dir. dir MUST be non-empty — see SafeGitCmd for why an empty dir is refused under `go test`.
func SafeGitCmd ¶ added in v0.16.4
SafeGitCmd constructs an *exec.Cmd for a git invocation with built-in test-mode safety:
- Production: behaves like exec.Command("git", args...) with cmd.Dir set to dir when dir != "".
- Test mode (`go test`): when dir is empty AND the subcommand is mutating, returns a Cmd that points at an unrunnable sentinel path so the test fails loudly instead of mutating the host repo.
Pass dir="" only for read-only commands (status, diff, log, …) when you intentionally want the process CWD. Mutating commands MUST supply a working directory.
func TruncateRunes ¶
Types ¶
type CommitExecutor ¶
type CommitExecutor struct {
Client api.ClientInterface
UserMessage string
UserInstructions string
// Dir is the working directory for git commands. If empty, the current directory is used.
Dir string
// contains filtered or unexported fields
}
CommitExecutor provides methods for executing git commits with message generation.
func NewCommitExecutor ¶
func NewCommitExecutor(client api.ClientInterface, userMessage, userInstructions string) *CommitExecutor
NewCommitExecutor creates a new commit executor with the given configuration.
func NewCommitExecutorInDir ¶
func NewCommitExecutorInDir(client api.ClientInterface, userMessage, userInstructions, dir string) *CommitExecutor
NewCommitExecutorInDir creates a new commit executor that runs git commands in the specified directory.
func NewCommitExecutorWithSecurityCheck ¶
func NewCommitExecutorWithSecurityCheck(client api.ClientInterface, userMessage, userInstructions string, secretCheck SecretCheckHandler) *CommitExecutor
NewCommitExecutorWithSecurityCheck creates a CommitExecutor with a security check callback.
func (*CommitExecutor) ExecuteCommit ¶
func (e *CommitExecutor) ExecuteCommit() (string, error)
ExecuteCommit performs the complete commit operation: 1. Gets staged files and validates there are changes 2. Gets the current branch name 3. Parses file changes into structured format 4. Gets the staged diff 5. Generates commit message (using provided message, LLM, or fallback) 6. Creates commit using a secure temp file 7. Returns the commit hash
This function is designed to be reusable by both the commit tool and commit flow.
type CommitFileChange ¶
CommitFileChange describes a staged file with git status code.
type CommitMessageOptions ¶
type CommitMessageOptions struct {
Diff string
Branch string
FileChanges []CommitFileChange
UserInstructions string
}
CommitMessageOptions configures commit message generation behavior.
type CommitMessageResult ¶
CommitMessageResult contains generated message and diagnostics.
func GenerateCommitMessageFromStagedDiff ¶
func GenerateCommitMessageFromStagedDiff(client api.ClientInterface, opts CommitMessageOptions) (*CommitMessageResult, error)
GenerateCommitMessageFromStagedDiff generates commit text using the same two-pass title+description algorithm used by /commit.
type CommitOptions ¶
CommitOptions contains options for commit operations
type CommitSecurityResult ¶
type CommitSecurityResult struct {
HasConcerns bool
Concerns []security.DetectedSecret
}
CommitSecurityResult holds the result of security checking staged files.
func CheckStagedFilesForSecurityCredentials ¶
func CheckStagedFilesForSecurityCredentials(logger *utils.Logger, dir string) CommitSecurityResult
CheckStagedFilesForSecurityCredentials checks staged files for security credentials and returns a detailed result with the specific concerns found.
type PullRequestRequest ¶ added in v0.16.12
type PullRequestRequest struct {
Title string // PR title (required)
Body string // PR body; synthesised from commits when empty
Base string // target branch; default = repo default branch
Head string // source branch; default = current HEAD branch
Draft bool
Reviewers []string // usernames (API-only; ignored by gh CLI fallback)
}
PullRequestRequest describes a pull request to create.
type PullRequestResult ¶ added in v0.16.12
type PullRequestResult struct {
URL string `json:"html_url"`
Number int `json:"number"`
State string `json:"state"` // "open" or "closed"
}
PullRequestResult holds the outcome of a successful PR creation.
func CreatePullRequest ¶ added in v0.16.12
func CreatePullRequest(ctx context.Context, repoDir string, req PullRequestRequest) (*PullRequestResult, error)
CreatePullRequest creates a pull request on GitHub for the given repoDir.
Resolution order:
- GitHub REST API (credential store → GH_TOKEN env var)
- gh pr create shell-out (fallback when no token available)
- Structured error with the exact gh command the user can run manually
If req.Head is empty, the current branch name is used. If req.Base is empty, the repository's default branch is inferred. If req.Body is empty, a body is synthesised from commit messages between base and head.
type SecretCheckHandler ¶
type SecretCheckHandler func(securityResult CommitSecurityResult) bool
SecretCheckHandler is a callback for handling detected secrets in commit flow. It receives the security result and returns whether to proceed with the commit. Return true to proceed, false to abort.