Skip to content

feat(config): remote auto-sync (autoPull + autoPush) across CLI, web and MCP#700

Closed
tuxo83 wants to merge 2 commits into
MrLesk:mainfrom
tuxo83:feat/remote-auto-sync
Closed

feat(config): remote auto-sync (autoPull + autoPush) across CLI, web and MCP#700
tuxo83 wants to merge 2 commits into
MrLesk:mainfrom
tuxo83:feat/remote-auto-sync

Conversation

@tuxo83

@tuxo83 tuxo83 commented Jun 27, 2026

Copy link
Copy Markdown

feat(config): remote auto-sync — autoPull before / autoPush after, across CLI, web and MCP

Summary

Two complementary, opt-in config flags that keep a shared Backlog.md repository in
sync with its git remote automatically — no per-clone git hooks required:

  • autoPull — run git pull --rebase --autostash before an operation, so
    reads/writes work against the latest remote state.
  • autoPush — run git push after every commit, so changes are shared
    immediately.

Both are off by default and both cover every entry point that touches the
repo: the CLI, the web UI and the MCP server. Together they make a hosted
Backlog.md (web + MCP behind a gateway) stay consistent with humans using the CLI.

These two flags are presented in one PR because they are two halves of a single
capability and touch the same config plumbing (type, migration, load/save/
serialize, CLI keys + help). Splitting them would force an artificial stacked
rebase. The branch has two clean commits (autoPull, then autoPush) for review.

autoPull — sync before each operation

  • CLI: a global commander preAction hook pulls before each command.
  • MCP: the server pulls before each tool call (an AI reads/writes the latest).
  • Web: each API request pulls first — mutations always pull (a commit/push
    is never built on a stale base); reads are throttled
    (AUTO_PULL_READ_THROTTLE_MS = 2000ms) so UI polling cannot flood the remote.

autoPush — push after each commit

  • Implemented at the commit layer (git/operations.ts), so a single seam covers
    CLI + web + MCP. Native replacement for a .git/hooks/post-commit "git push" hack.
  • Pushes the current branch (git push origin HEAD).

Behavior & safety (both)

  • Opt-in: defaults false → no change for existing users.
  • Gated by remoteOperations and the presence of a remote (skipped for
    --no-git / filesystem-only, or when no remote is configured).
  • Never block the operation: pull() / push() swallow expected failures
    (network down, no upstream, non-fast-forward, rebase conflicts) — the command,
    request or tool call always proceeds. autoPull uses --rebase --autostash, so
    local uncommitted edits are stashed/replayed and never clobbered.
  • Like bypassGitHooks/filesystemOnly, neither flag is added to needsMigration,
    so existing projects are not force-rewritten on load (absent ⇒ false).

Usage

backlog config set autoPull true    # auto_pull: true
backlog config set autoPush true    # auto_push: true

backlog board        # CLI: pull before
backlog task create  # commit, then push
backlog browser      # web: pull before requests, push after writes
backlog mcp start    # MCP: pull before each tool call, push after writes

What's included

  • src/types/index.tsautoPull?, autoPush?.
  • src/core/config-migration.ts — defaults false (intentionally not in needsMigration).
  • src/file-system/operations.tsauto_pull / auto_push load + save (snake_case).
  • src/git/operations.tspull(); push() + autoPushIfEnabled() after the 4 commit builders.
  • src/cli.tspreAction pull hook; config get/set for both; config-key lists + help.
  • src/mcp/server.tsmaybeAutoPull() before each tool call.
  • src/server/index.tsmaybeAutoPull(force) + applyAutoPullToRoutes() (mutations force, reads throttled).
  • README.md — documented in the Configuration section.
  • Tests:
    • src/test/auto-push.test.ts — real bare-remote push after a Core commit; no push when disabled / when remoteOperations off.
    • src/test/mcp-auto-pull.test.ts — MCP pulls a collaborator's pushed commit before a tool call (and not when disabled).
    • src/test/server-auto-pull.test.ts — the web server pulls on an API request (and not when disabled).
    • src/test/config-commands.test.ts — save/reload roundtrip for both flags.

Testing

  • bunx tsc --noEmit → clean. npx biome check . (changed files) → clean.
  • bun test (auto-push, mcp-auto-pull, server-auto-pull, config, cli, mcp suites) → 126 pass / 0 fail, including a real git push reaching a bare remote and a real git pull of a collaborator's commit via both the MCP and web paths.

Related Tasks

Associated backlog task to be created per the PR template (suggested: "Remote
auto-sync: autoPull before / autoPush after, across CLI/web/MCP", atomic with the
acceptance criteria above). Happy to split into two tasks/PRs if preferred.

tuxo83 added 2 commits June 27, 2026 07:28
…ion (CLI, web and MCP)

When `auto_pull` is enabled, Backlog.md runs `git pull --rebase --autostash`
before serving an operation, so reads and writes work against the latest remote
state. Opt-in, off by default.

Covers every entry point:
- CLI: a commander preAction hook pulls before each command.
- MCP: the server pulls before each tool call (so an AI reads/writes the latest).
- Web: each API request pulls first — mutations always pull (so a commit/push is
  never built on a stale base); reads are throttled (AUTO_PULL_READ_THROTTLE_MS)
  so UI polling cannot flood the remote.

New `pull()` git op: rebase+autostash, gated by `remote_operations` and the
presence of a remote; never throws (network / no upstream / conflicts are
swallowed) so it can't block a command, tool call or request.

Config plumbing: type, migration default, load/save/serialize, CLI get/set,
config-key lists and help text.

Note: like `bypassGitHooks`/`filesystemOnly`, `autoPull` is intentionally NOT
added to needsMigration — an absent value is treated as false and existing
projects are not force-rewritten on load.

Tests: CLI roundtrip of the config flag; MCP pulls a collaborator's pushed
commit before a tool call (and does not when disabled); the web server pulls on
an API request before serving it (and does not when disabled).
Symmetric counterpart of autoPull. When `auto_push` is enabled, Backlog.md
runs `git push` right after each commit, so changes are shared immediately
without a per-clone post-commit hook.

Implemented at the commit layer (git/operations.ts), so it covers every entry
point that writes through Core: the CLI, the web UI and the MCP server. This is
the native replacement for a `.git/hooks/post-commit` "git push" hack.

- Opt-in, off by default: `auto_push: false`.
- New `push()` git op: pushes the current HEAD; gated by `remote_operations`
  and the presence of a remote; never throws (network / non-fast-forward /
  no upstream are swallowed) so it can't block a commit.
- `autoPushIfEnabled()` is called after each of the 4 commit builders.
- Config plumbing: type, migration default, load/save/serialize, CLI
  get/set, and the config-key lists + help text.

Note: like `bypassGitHooks`/`filesystemOnly`, `autoPush` is intentionally NOT
added to needsMigration — an absent value is treated as false and existing
projects are not force-rewritten.

Tests: real bare-remote push verified after a Core commit; no push when
disabled; no push when remoteOperations is off; config save/reload roundtrip.
@MrLesk

MrLesk commented Jul 1, 2026

Copy link
Copy Markdown
Owner

Alex's Agent: Thanks for the detailed PR and tests. I am going to close this due to current project scope and risk rather than iterate on the implementation here.

Backlog.md is keeping git behavior explicit and user-directed, and automatic git pull/push across CLI, web requests, and MCP tool calls changes the core git behavior and risk profile too broadly, even as opt-in config. In particular, web/MCP-triggered remote mutation, pre-command pulls, post-commit pushes, and swallowed pull/push failures are not behavior we want to add under the current project direction.

If there is a follow-up worth splitting out, keep it narrow and non-mutating: a docs/config clarification around the existing remoteOperations behavior and the expectation that users run explicit git sync workflows outside Backlog.md. I would not carry over the autoPull/autoPush feature surface into a smaller PR.

Closing as out of scope/deferred.

Future PRs in this area should link an issue first, or open one before implementation so scope can be agreed.

@MrLesk MrLesk closed this Jul 1, 2026
@tuxo83 tuxo83 deleted the feat/remote-auto-sync branch July 5, 2026 18:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants