hillclimb 0.4.1 → 0.4.3
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.
- package/dist/cli.js +71 -34
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -11150,7 +11150,13 @@ async function eventContext(tool, payload) {
|
|
|
11150
11150
|
conversationId: stringOrNull(payload.conversation_id),
|
|
11151
11151
|
turnId,
|
|
11152
11152
|
eventNonce,
|
|
11153
|
-
|
|
11153
|
+
// Only per-turn stop events need the transcript to disambiguate (they
|
|
11154
|
+
// often lack a turn id); sessionEnd is keyed by sessionId. Folding it in
|
|
11155
|
+
// for sessionEnd would diverge the agent/git eventIds whenever the two
|
|
11156
|
+
// hooks send different payloads — e.g. the opencode plugin passes
|
|
11157
|
+
// transcript_path to the upload spawn but not the git-traces spawn,
|
|
11158
|
+
// causing a 60s orphan wait and a duplicate debug-log upload.
|
|
11159
|
+
...eventKind === "stop" ? await transcriptFingerprint(payload) : {}
|
|
11154
11160
|
};
|
|
11155
11161
|
const eventId = crypto.createHash("sha256").update(JSON.stringify(fingerprint)).digest("hex").slice(0, 32);
|
|
11156
11162
|
return {
|
|
@@ -13619,8 +13625,9 @@ function captureSnapshotSha(repoRoot) {
|
|
|
13619
13625
|
}
|
|
13620
13626
|
return git(repoRoot, ["rev-parse", "HEAD"]);
|
|
13621
13627
|
}
|
|
13622
|
-
function recordOmittedSnapshotFile(omittedFiles, file) {
|
|
13628
|
+
function recordOmittedSnapshotFile(omittedFiles, file, options = {}) {
|
|
13623
13629
|
omittedFiles?.push(file);
|
|
13630
|
+
if (options.log === false) return;
|
|
13624
13631
|
const action = file.tracked ? "omitting tracked" : "skipping untracked";
|
|
13625
13632
|
appendLog(
|
|
13626
13633
|
"warn",
|
|
@@ -13643,7 +13650,7 @@ function parseLsTreeLongZ(output) {
|
|
|
13643
13650
|
}
|
|
13644
13651
|
return entries;
|
|
13645
13652
|
}
|
|
13646
|
-
function listOversizedTreeFiles(repoRoot, treeSha,
|
|
13653
|
+
function listOversizedTreeFiles(repoRoot, treeSha, options = {}) {
|
|
13647
13654
|
const output = gitBuffer(repoRoot, ["ls-tree", "-r", "-l", "-z", treeSha]);
|
|
13648
13655
|
const oversized = [];
|
|
13649
13656
|
for (const entry of parseLsTreeLongZ(output)) {
|
|
@@ -13656,7 +13663,9 @@ function listOversizedTreeFiles(repoRoot, treeSha, omittedFiles) {
|
|
|
13656
13663
|
gitObjectSha: entry.sha
|
|
13657
13664
|
};
|
|
13658
13665
|
oversized.push(file);
|
|
13659
|
-
recordOmittedSnapshotFile(omittedFiles, file
|
|
13666
|
+
recordOmittedSnapshotFile(options.omittedFiles, file, {
|
|
13667
|
+
log: options.log
|
|
13668
|
+
});
|
|
13660
13669
|
}
|
|
13661
13670
|
return oversized;
|
|
13662
13671
|
}
|
|
@@ -13667,6 +13676,29 @@ function removePathsFromIndex(repoRoot, env, paths) {
|
|
|
13667
13676
|
env
|
|
13668
13677
|
});
|
|
13669
13678
|
}
|
|
13679
|
+
function filterOversizedFilesFromTree(repoRoot, treeSha, options = {}) {
|
|
13680
|
+
const oversizedFiles = listOversizedTreeFiles(repoRoot, treeSha, options);
|
|
13681
|
+
if (oversizedFiles.length === 0) return treeSha;
|
|
13682
|
+
const tmpIndex = path14.join(
|
|
13683
|
+
os6.tmpdir(),
|
|
13684
|
+
`hillclimb-filter-${Date.now()}-${process.pid}`
|
|
13685
|
+
);
|
|
13686
|
+
const env = { ...process.env, GIT_INDEX_FILE: tmpIndex };
|
|
13687
|
+
try {
|
|
13688
|
+
gitWithEnv(repoRoot, ["read-tree", treeSha], env);
|
|
13689
|
+
removePathsFromIndex(
|
|
13690
|
+
repoRoot,
|
|
13691
|
+
env,
|
|
13692
|
+
oversizedFiles.map((file) => file.path)
|
|
13693
|
+
);
|
|
13694
|
+
return gitWithEnv(repoRoot, ["write-tree"], env);
|
|
13695
|
+
} finally {
|
|
13696
|
+
try {
|
|
13697
|
+
fs11.unlinkSync(tmpIndex);
|
|
13698
|
+
} catch {
|
|
13699
|
+
}
|
|
13700
|
+
}
|
|
13701
|
+
}
|
|
13670
13702
|
function buildUntrackedTree(repoRoot, omittedFiles) {
|
|
13671
13703
|
const list = git(repoRoot, [
|
|
13672
13704
|
"ls-files",
|
|
@@ -13714,46 +13746,40 @@ function buildUntrackedTree(repoRoot, omittedFiles) {
|
|
|
13714
13746
|
}
|
|
13715
13747
|
function buildSnapshotTree(repoRoot, stashSha, options = {}) {
|
|
13716
13748
|
const trackedTree = git(repoRoot, ["rev-parse", `${stashSha}^{tree}`]);
|
|
13717
|
-
const
|
|
13749
|
+
const filteredTrackedTree = filterOversizedFilesFromTree(
|
|
13718
13750
|
repoRoot,
|
|
13719
13751
|
trackedTree,
|
|
13720
|
-
|
|
13752
|
+
{
|
|
13753
|
+
omittedFiles: options.omittedFiles
|
|
13754
|
+
}
|
|
13721
13755
|
);
|
|
13722
13756
|
const untrackedTree = buildUntrackedTree(repoRoot, options.omittedFiles);
|
|
13723
|
-
if (
|
|
13724
|
-
return
|
|
13725
|
-
}
|
|
13757
|
+
if (!untrackedTree || untrackedTree === EMPTY_TREE_SHA)
|
|
13758
|
+
return filteredTrackedTree;
|
|
13726
13759
|
const tmpIndex = path14.join(
|
|
13727
13760
|
os6.tmpdir(),
|
|
13728
13761
|
`hillclimb-index-${Date.now()}-${process.pid}`
|
|
13729
13762
|
);
|
|
13730
13763
|
const env = { ...process.env, GIT_INDEX_FILE: tmpIndex };
|
|
13731
13764
|
try {
|
|
13732
|
-
gitWithEnv(repoRoot, ["read-tree",
|
|
13733
|
-
|
|
13765
|
+
gitWithEnv(repoRoot, ["read-tree", filteredTrackedTree], env);
|
|
13766
|
+
const untrackedList = gitBuffer(
|
|
13734
13767
|
repoRoot,
|
|
13735
|
-
|
|
13736
|
-
|
|
13737
|
-
|
|
13738
|
-
if (untrackedTree && untrackedTree !== EMPTY_TREE_SHA) {
|
|
13739
|
-
const untrackedList = gitBuffer(
|
|
13740
|
-
repoRoot,
|
|
13741
|
-
["ls-tree", "-r", untrackedTree],
|
|
13742
|
-
{
|
|
13743
|
-
env
|
|
13744
|
-
}
|
|
13745
|
-
).toString("utf-8");
|
|
13746
|
-
const indexInfo = untrackedList.split("\n").filter(Boolean).map((line) => {
|
|
13747
|
-
const [meta, filePath] = line.split(" ");
|
|
13748
|
-
const [mode, , sha] = meta.split(/\s+/);
|
|
13749
|
-
return `${mode} ${sha} ${filePath}`;
|
|
13750
|
-
}).join("\n");
|
|
13751
|
-
if (indexInfo) {
|
|
13752
|
-
gitBuffer(repoRoot, ["update-index", "--index-info"], {
|
|
13753
|
-
input: indexInfo,
|
|
13754
|
-
env
|
|
13755
|
-
});
|
|
13768
|
+
["ls-tree", "-r", untrackedTree],
|
|
13769
|
+
{
|
|
13770
|
+
env
|
|
13756
13771
|
}
|
|
13772
|
+
).toString("utf-8");
|
|
13773
|
+
const indexInfo = untrackedList.split("\n").filter(Boolean).map((line) => {
|
|
13774
|
+
const [meta, filePath] = line.split(" ");
|
|
13775
|
+
const [mode, , sha] = meta.split(/\s+/);
|
|
13776
|
+
return `${mode} ${sha} ${filePath}`;
|
|
13777
|
+
}).join("\n");
|
|
13778
|
+
if (indexInfo) {
|
|
13779
|
+
gitBuffer(repoRoot, ["update-index", "--index-info"], {
|
|
13780
|
+
input: indexInfo,
|
|
13781
|
+
env
|
|
13782
|
+
});
|
|
13757
13783
|
}
|
|
13758
13784
|
return gitWithEnv(repoRoot, ["write-tree"], env);
|
|
13759
13785
|
} finally {
|
|
@@ -13789,11 +13815,22 @@ function createBundleFromTree(repoRoot, treeSha, sessionId, label) {
|
|
|
13789
13815
|
}
|
|
13790
13816
|
function createTreeDiffPatchGz(repoRoot, fromTreeSha, toTreeSha) {
|
|
13791
13817
|
if (fromTreeSha === toTreeSha) return null;
|
|
13818
|
+
const filteredFromTreeSha = filterOversizedFilesFromTree(
|
|
13819
|
+
repoRoot,
|
|
13820
|
+
fromTreeSha,
|
|
13821
|
+
{
|
|
13822
|
+
log: false
|
|
13823
|
+
}
|
|
13824
|
+
);
|
|
13825
|
+
const filteredToTreeSha = filterOversizedFilesFromTree(repoRoot, toTreeSha, {
|
|
13826
|
+
log: false
|
|
13827
|
+
});
|
|
13828
|
+
if (filteredFromTreeSha === filteredToTreeSha) return null;
|
|
13792
13829
|
const diff = gitBuffer(repoRoot, [
|
|
13793
13830
|
"diff",
|
|
13794
13831
|
"--binary",
|
|
13795
|
-
|
|
13796
|
-
|
|
13832
|
+
filteredFromTreeSha,
|
|
13833
|
+
filteredToTreeSha
|
|
13797
13834
|
]);
|
|
13798
13835
|
if (diff.length === 0) return null;
|
|
13799
13836
|
return Buffer.from(gzipSync(diff));
|