Repository navigation
Conversation
Port OpenCode's snapshot approach (MIT-licensed, credit in snapshot.py) to record which workspace files each run changed and a unified diff, without touching the workspace's own .git. - New SnapshotStore (backend/openbot/runtime/snapshot.py): per-workspace dedicated git repo under .openbot/snapshots/<hash> — git add -A + write-tree before/after each run, diff-tree for changed files + unified diff. Concurrent bots share one workspace safely: in-process serialization per store, git's own index.lock for cross-process, and .openbot always excluded. - DB: migration 0023 adds changed_files (JSON) and diff (Text) to runs. - Runner: _snapshot_capture_before at run start, _snapshot_attach_terminal at completion/failure/cancellation; CLI agent path updated too. - API: RunOut schema exposes changed_files + diff. - Frontend: RunCard renders a 'Changed' section (file count, filenames, collapsible unified diff) when changed_files is non-empty, consistent with existing card style. - Tests: 7 tests in tests/test_snapshot.py covering store init, capture+diff, gitignore/OOB exclusion, no-change empty diff, and full runner wiring with actual tool calls. All values are best-effort: a failed snapshot never blocks the run.
regnull
force-pushed
the
feat/run-file-changes
branch
from
October 19, 2026 11:22
28b48d4 to
46670d6
Compare
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.
Summary
Port OpenCode's MIT-licensed snapshot approach (
snapshot/service) so every run records which workspace files it changed and a unified diff — all without touching the workspace's own.git.Closes #257.
How It Works
Each workspace gets a dedicated, bare git repository under
.openbot/snapshots/<sha256-of-workspace-path>. Before a run, the runner fingerprints the workspace withgit add -A && git write-treeagainst that store; after the run ends (completed / failed / cancelled / undeliverable human question), it captures a second tree and diffs the two withgit diff-tree --name-status -r -z(for the file list) andgit diff-tree -p(for the unified diff).The store's index is rebuilt from the worktree on every capture — three concurrent bots editing the same workspace never interleave writes because captures are serialized per-storedir (in-process
asyncio.Lock), and git itself providesindex.lockfor cross-process safety.What Changed
backend/openbot/runtime/snapshot.pySnapshotStoreclass +store_for_runhelper — entire snapshot/diff engine (credit comment links OpenCode MIT source)backend/openbot/db/migrations/versions/0023_run_snapshots.pychanged_files(JSON) anddiff(Text) columns torunsbackend/tests/test_snapshot.pybackend/openbot/db/models.pyRun.changed_files+Run.diffmapped columnsbackend/openbot/api/schemas.pyRunOut.changed_files+RunOut.diffbackend/openbot/runtime/runner.py_snapshot_capture_before,_snapshot_store_after,_snapshot_attach_terminalmethods; wired into execute() at start and all terminal paths (completed / cancelled / failed / undeliverable ask_human)backend/openbot/runtime/cli_agents/run.py_snapshot_attach_terminalinstead of_set_statusfor its terminal statusfrontend/src/api/types.tsRuninterface getschanged_files?: string[] | null+diff?: string | nullfrontend/src/components/RunCard.tsx<details>unified diffDesign Decisions
changed_filessimply staysNone..gitignore,.git/info/exclude, and global excludes..openbotis additionally always excluded via the store'sinfo/exclude, so OpenBot state is never recorded as a run's changes.--no-renamesondiff-treematches OpenCode's behavior: one run's delete+recreate of a file shows as delete+add, which is clearer in a per-run audit.ask_humanre-entersexecute()on resume; its original before-tree is keyed inself._snapshot_beforeso the final diff spans the entire multi-segment run.Test Results
ruff checkcleanelectron/main.test.ts(unrelated--root-directorytest, also fails onmain),tsc --noEmitclean,pnpm lint0 errors (1 pre-existingset-state-in-effectwarning)