/** * Sidecar git helper — manages the single shared git repo at * `~/.skaile/sidecars/` (PR-3 § D.5). * * Each sidecar lives in its own subdirectory under ``. All sidecars * share one `.git/` so users can push the entire root to a personal remote * (e.g. their own `dotfiles` repo) without juggling N repos. * * `ensureInitialized()` is idempotent — safe to call on every command. The * helper applies a fallback `user.name` / `user.email` only when the global * git config is missing those keys, so it never overrides a user's own * identity. * * Mutating commands (`commit()`) are no-ops when `skip: true` is passed; this * is how the CLI's `--no-commit` flag flows through. * * Shells out to the system `git` binary via `child_process` — keeps the * dependency surface minimal and matches the rest of the agent-framework's * pattern (no `simple-git` / `isomorphic-git`). * * @docLink packages/library/concepts#sidecar-git */ /** * Result of a raw `git` invocation via {@link SidecarGit.runRaw}. * * @docLink packages/library/concepts#sidecar-git */ export interface GitInvocationResult { stdout: string; stderr: string; exitCode: number; } /** * Options accepted by {@link SidecarGit.commit}. */ export interface SidecarCommitOptions { /** Skip the commit entirely. Used by the CLI's `--no-commit` flag. */ skip?: boolean; } /** * Git operations over the shared sidecar root. * * One instance per CLI invocation is the typical pattern; the helper is * stateless beyond the `rootDir`. * * @docLink packages/library/concepts#sidecar-git */ export declare class SidecarGit { readonly rootDir: string; constructor(rootDir: string); /** * Initialize the sidecar root if it doesn't yet exist. * * Steps (idempotent — each is a no-op when already present): * 1. `mkdir -p ` * 2. `git init -b main ` if `/.git` is missing * 3. Write `.gitattributes` (`* text=auto eol=lf`) if missing * 4. Write `README.md` if missing * 5. Apply fallback `user.name` / `user.email` to the repo config if * the global config is missing them * 6. Create the seed commit (`chore: initialize sidecar manifests`) if * the repo has no commits yet * * Subsequent calls don't reset config, so a user who overrode the * identity manually keeps their override. * * @docLink packages/library/concepts#sidecar-git */ ensureInitialized(): Promise; /** * Stage everything under `//` and create a commit. * * Idempotent: if there are no staged changes after `git add`, the commit * is skipped (and resolves successfully — a no-op is fine). * * @param slug - Sidecar slug (subdirectory name) * @param message - Commit message (conventional-commits style preferred; * the CLI uses `feat(): create sidecar...`, `chore(): ...`) * @param opts - `{ skip: true }` short-circuits without staging or committing */ commit(slug: string, message: string, opts?: SidecarCommitOptions): Promise; /** * Check whether the sidecar repo has uncommitted changes. * * @returns `true` when `git status --porcelain` has any output. */ hasChanges(): Promise; /** * Run an arbitrary `git -C ` invocation and return the * captured stdout/stderr + exit code. * * Used by `skaile source sidecar git -- ` so users don't have to * `cd ~/.skaile/sidecars` to operate the repo manually. * * @param args - Git arguments (no leading `git` token) * @returns Combined output + exit code; never throws on non-zero exit * @docLink packages/library/concepts#sidecar-git */ runRaw(args: string[]): Promise; private spawn; private hasGlobalGitConfig; private hasAnyCommit; } //# sourceMappingURL=sidecar-git.d.ts.map