@bivy/bivy 0.16.14 → 0.16.15-staging.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -73,17 +73,46 @@ export function captureDirtyPatch(repoDir, opts = {}) {
73
73
  }
74
74
  return { patch, untracked };
75
75
  }
76
- /** Capture a non-git workspace for a fork. Symlinks are recorded, never followed,
77
- * and .git is excluded as it is a repository boundary rather than workspace data. */
76
+ /** Git's file list preserves tracked files even when ignored, and applies nested
77
+ * ignore rules, negations, and local/global excludes to untracked files. Include
78
+ * ancestors so the walker can prune ignored directories before reading them.
79
+ * Plain directories retain full-snapshot behavior; other git failures abort. */
80
+ function snapshotGitPaths(root) {
81
+ const result = spawnSync("git", ["-C", root, "ls-files", "-z", "--cached", "--others", "--exclude-standard", "--", "."], {
82
+ encoding: "utf8", timeout: 10_000, maxBuffer: 64 * 1024 * 1024,
83
+ });
84
+ if (result.error)
85
+ throw result.error;
86
+ if (result.status !== 0) {
87
+ if (/not a git repository|outside a git work tree/i.test(result.stderr))
88
+ return undefined;
89
+ throw new Error(`Could not inspect the session workspace for snapshot files: ${result.stderr.trim() || result.signal || result.status}`);
90
+ }
91
+ const paths = new Set();
92
+ for (const file of result.stdout.split("\0").filter(Boolean)) {
93
+ let rel = path.normalize(file);
94
+ while (rel !== ".") {
95
+ paths.add(rel);
96
+ rel = path.dirname(rel);
97
+ }
98
+ }
99
+ return paths;
100
+ }
101
+ /** Capture a workspace for a fork. Git checkouts include tracked and non-ignored
102
+ * untracked files only. Symlinks are recorded, never followed, and root .git and
103
+ * .bivy metadata are excluded. */
78
104
  export function captureWorkspaceSnapshot(root, opts = {}) {
79
105
  const maxBytes = workspaceMaxBytes(opts.maxBytes);
80
106
  const entries = [];
107
+ const gitPaths = snapshotGitPaths(root);
81
108
  let byteLength = 0;
82
109
  const walk = (dir, prefix) => {
83
110
  for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
84
111
  if (!prefix && (entry.name === ".git" || entry.name === ".bivy"))
85
112
  continue;
86
113
  const rel = prefix ? path.join(prefix, entry.name) : entry.name;
114
+ if (gitPaths && !gitPaths.has(rel))
115
+ continue;
87
116
  const abs = path.join(dir, entry.name);
88
117
  const stat = fs.lstatSync(abs);
89
118
  if (stat.isDirectory()) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bivy/bivy",
3
- "version": "0.16.14",
3
+ "version": "0.16.15-staging.2",
4
4
  "type": "module",
5
5
  "license": "AGPL-3.0-only",
6
6
  "description": "Run coding agents on machines you own. Open-source, self-hostable agent workspace.",