hillclimb 0.9.0 → 0.9.1
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/main.js +56 -17
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -16831,7 +16831,7 @@ async function uploadArtifact(client, contributionId, filename, mimeType, buffer
|
|
|
16831
16831
|
}
|
|
16832
16832
|
|
|
16833
16833
|
// package.json
|
|
16834
|
-
var version = "0.9.
|
|
16834
|
+
var version = "0.9.1";
|
|
16835
16835
|
|
|
16836
16836
|
// src/version.ts
|
|
16837
16837
|
var CLI_VERSION = version;
|
|
@@ -16973,13 +16973,14 @@ function isPhantomClaudeHook(payload, toolOverride) {
|
|
|
16973
16973
|
var MAX_FORK_SWEEP_THREADS = 8;
|
|
16974
16974
|
async function runUploadInner(payload, options = {}) {
|
|
16975
16975
|
const outcome = await runUploadForSession(payload, options);
|
|
16976
|
-
|
|
16976
|
+
const settled = outcome === "uploaded" || outcome === "unchanged" || outcome === "skipped";
|
|
16977
|
+
if (!options.sweptFrom && payload.tool === "codex" && settled) {
|
|
16977
16978
|
await sweepCodexForkTranscripts(payload);
|
|
16978
16979
|
}
|
|
16979
|
-
if (!options.sweptFrom && payload.tool === "claude" &&
|
|
16980
|
+
if (!options.sweptFrom && payload.tool === "claude" && settled) {
|
|
16980
16981
|
await sweepClaudeSubagentTranscripts(payload);
|
|
16981
16982
|
}
|
|
16982
|
-
if (!options.sweptFrom &&
|
|
16983
|
+
if (!options.sweptFrom && settled) {
|
|
16983
16984
|
await sweepStrandedAgentUploads(resolveHookSessionId(payload));
|
|
16984
16985
|
}
|
|
16985
16986
|
return outcome;
|
|
@@ -17020,7 +17021,13 @@ async function sweepClaudeSubagentTranscripts(payload) {
|
|
|
17020
17021
|
const project = await findProjectForCwd(cwd);
|
|
17021
17022
|
if (!project) return;
|
|
17022
17023
|
files.sort((a, b) => b.modifiedMs - a.modifiedMs);
|
|
17023
|
-
const tally = {
|
|
17024
|
+
const tally = {
|
|
17025
|
+
uploaded: 0,
|
|
17026
|
+
unchanged: 0,
|
|
17027
|
+
pending: 0,
|
|
17028
|
+
skipped: 0,
|
|
17029
|
+
failed: 0
|
|
17030
|
+
};
|
|
17024
17031
|
for (const entry of files.slice(0, MAX_SUBAGENT_SWEEP)) {
|
|
17025
17032
|
const subagentSessionId = `agent-${entry.agentId}`;
|
|
17026
17033
|
try {
|
|
@@ -17039,6 +17046,7 @@ async function sweepClaudeSubagentTranscripts(payload) {
|
|
|
17039
17046
|
}
|
|
17040
17047
|
);
|
|
17041
17048
|
if (outcome === "uploaded") tally.uploaded++;
|
|
17049
|
+
else if (outcome === "unchanged") tally.unchanged++;
|
|
17042
17050
|
else if (outcome === "pending") tally.pending++;
|
|
17043
17051
|
else tally.skipped++;
|
|
17044
17052
|
appendLog(
|
|
@@ -17055,7 +17063,7 @@ async function sweepClaudeSubagentTranscripts(payload) {
|
|
|
17055
17063
|
}
|
|
17056
17064
|
appendLog(
|
|
17057
17065
|
"info",
|
|
17058
|
-
`[${parentSessionId}] subagent sweep (found=${files.length}, uploaded=${tally.uploaded}, pending=${tally.pending}, skipped=${tally.skipped}, failed=${tally.failed})`
|
|
17066
|
+
`[${parentSessionId}] subagent sweep (found=${files.length}, uploaded=${tally.uploaded}, unchanged=${tally.unchanged}, pending=${tally.pending}, skipped=${tally.skipped}, failed=${tally.failed})`
|
|
17059
17067
|
);
|
|
17060
17068
|
} catch (err) {
|
|
17061
17069
|
appendLog(
|
|
@@ -17178,7 +17186,13 @@ async function sweepCodexForkTranscripts(payload) {
|
|
|
17178
17186
|
registeredRoots
|
|
17179
17187
|
});
|
|
17180
17188
|
if (discovery.forks.length === 0) return;
|
|
17181
|
-
const tally = {
|
|
17189
|
+
const tally = {
|
|
17190
|
+
uploaded: 0,
|
|
17191
|
+
unchanged: 0,
|
|
17192
|
+
pending: 0,
|
|
17193
|
+
skipped: 0,
|
|
17194
|
+
failed: 0
|
|
17195
|
+
};
|
|
17182
17196
|
for (const fork of discovery.forks.slice(0, MAX_FORK_SWEEP_THREADS)) {
|
|
17183
17197
|
const project = await findProjectForCwd(fork.cwd) ?? parent;
|
|
17184
17198
|
const forkPayload = {
|
|
@@ -17194,6 +17208,7 @@ async function sweepCodexForkTranscripts(payload) {
|
|
|
17194
17208
|
sweptFrom: parentSessionId
|
|
17195
17209
|
});
|
|
17196
17210
|
if (outcome === "uploaded") tally.uploaded++;
|
|
17211
|
+
else if (outcome === "unchanged") tally.unchanged++;
|
|
17197
17212
|
else if (outcome === "pending") tally.pending++;
|
|
17198
17213
|
else tally.skipped++;
|
|
17199
17214
|
appendLog(
|
|
@@ -17210,7 +17225,7 @@ async function sweepCodexForkTranscripts(payload) {
|
|
|
17210
17225
|
}
|
|
17211
17226
|
appendLog(
|
|
17212
17227
|
"info",
|
|
17213
|
-
`[${parentSessionId}] fork sweep (scannedRollouts=${discovery.scannedRollouts}, forks=${discovery.forks.length}, uploaded=${tally.uploaded}, pending=${tally.pending}, skipped=${tally.skipped}, failed=${tally.failed})`
|
|
17228
|
+
`[${parentSessionId}] fork sweep (scannedRollouts=${discovery.scannedRollouts}, forks=${discovery.forks.length}, uploaded=${tally.uploaded}, unchanged=${tally.unchanged}, pending=${tally.pending}, skipped=${tally.skipped}, failed=${tally.failed})`
|
|
17214
17229
|
);
|
|
17215
17230
|
} catch (err) {
|
|
17216
17231
|
appendLog(
|
|
@@ -17219,6 +17234,13 @@ async function sweepCodexForkTranscripts(payload) {
|
|
|
17219
17234
|
);
|
|
17220
17235
|
}
|
|
17221
17236
|
}
|
|
17237
|
+
async function settledOutcome(before, drained, repoRoot, sourceTool, sessionId) {
|
|
17238
|
+
if (!drained) return "pending";
|
|
17239
|
+
const after = await readUploadState(repoRoot, sourceTool, sessionId);
|
|
17240
|
+
if (!after) return "unchanged";
|
|
17241
|
+
if (!before) return "uploaded";
|
|
17242
|
+
return after.uploadCount !== before.uploadCount || after.lastUploadedAt !== before.lastUploadedAt ? "uploaded" : "unchanged";
|
|
17243
|
+
}
|
|
17222
17244
|
async function runUploadForSession(payload, options) {
|
|
17223
17245
|
if (isPhantomClaudeHook(payload)) {
|
|
17224
17246
|
appendLog("info", "upload: skipping phantom Claude hook fired by Cursor");
|
|
@@ -17265,7 +17287,8 @@ async function runUploadForSession(payload, options) {
|
|
|
17265
17287
|
"info",
|
|
17266
17288
|
`[${sessionId}] replaying ${pending.length} pending capture(s) without reading the live transcript`
|
|
17267
17289
|
);
|
|
17268
|
-
|
|
17290
|
+
const before2 = await readUploadState(repoRoot, sourceTool, sessionId);
|
|
17291
|
+
const drained2 = await drainCapturedSessions({
|
|
17269
17292
|
sessionId,
|
|
17270
17293
|
repoRoot,
|
|
17271
17294
|
config,
|
|
@@ -17273,7 +17296,8 @@ async function runUploadForSession(payload, options) {
|
|
|
17273
17296
|
eventKind: eventKind2,
|
|
17274
17297
|
recordedAt,
|
|
17275
17298
|
transcriptPath: firstPending.transcriptPath
|
|
17276
|
-
})
|
|
17299
|
+
});
|
|
17300
|
+
return settledOutcome(before2, drained2, repoRoot, sourceTool, sessionId);
|
|
17277
17301
|
};
|
|
17278
17302
|
const transcriptPath = await resolveTranscriptPath(
|
|
17279
17303
|
payload,
|
|
@@ -17330,7 +17354,8 @@ async function runUploadForSession(payload, options) {
|
|
|
17330
17354
|
);
|
|
17331
17355
|
return "skipped";
|
|
17332
17356
|
}
|
|
17333
|
-
const
|
|
17357
|
+
const before = await readUploadState(repoRoot, sourceTool, sessionId);
|
|
17358
|
+
const drained = await captureAndUploadSession({
|
|
17334
17359
|
sessionId,
|
|
17335
17360
|
transcriptPath: transcriptResolved,
|
|
17336
17361
|
repoRoot,
|
|
@@ -17340,7 +17365,7 @@ async function runUploadForSession(payload, options) {
|
|
|
17340
17365
|
recordedAt,
|
|
17341
17366
|
subagent: options.subagent
|
|
17342
17367
|
});
|
|
17343
|
-
return
|
|
17368
|
+
return settledOutcome(before, drained, repoRoot, sourceTool, sessionId);
|
|
17344
17369
|
}
|
|
17345
17370
|
var AGENT_MAX_UPLOAD_BYTES = 1024 * 1024 * 1024;
|
|
17346
17371
|
function makeTranscriptGroup(repoRoot, sourceTool, transcriptPath, content) {
|
|
@@ -20402,6 +20427,7 @@ async function sweepCodexForkCaptures(params) {
|
|
|
20402
20427
|
worktree: 0,
|
|
20403
20428
|
sameTree: 0,
|
|
20404
20429
|
unrelated: 0,
|
|
20430
|
+
deferred: 0,
|
|
20405
20431
|
initialized: 0,
|
|
20406
20432
|
uploaded: 0,
|
|
20407
20433
|
unchanged: 0,
|
|
@@ -20409,8 +20435,14 @@ async function sweepCodexForkCaptures(params) {
|
|
|
20409
20435
|
failed: 0,
|
|
20410
20436
|
skipped: 0
|
|
20411
20437
|
};
|
|
20412
|
-
|
|
20413
|
-
|
|
20438
|
+
const targets = /* @__PURE__ */ new Map();
|
|
20439
|
+
const hooked = /* @__PURE__ */ new Set();
|
|
20440
|
+
for (const fork of discovery.forks) {
|
|
20441
|
+
let target = targets.get(fork.cwd);
|
|
20442
|
+
if (target === void 0) {
|
|
20443
|
+
target = await resolveForkTarget(fork.cwd, repos);
|
|
20444
|
+
targets.set(fork.cwd, target);
|
|
20445
|
+
}
|
|
20414
20446
|
if (!target) {
|
|
20415
20447
|
tally.unrelated++;
|
|
20416
20448
|
continue;
|
|
@@ -20419,12 +20451,19 @@ async function sweepCodexForkCaptures(params) {
|
|
|
20419
20451
|
tally.sameTree++;
|
|
20420
20452
|
continue;
|
|
20421
20453
|
}
|
|
20422
|
-
tally.worktree++;
|
|
20423
20454
|
const repo = {
|
|
20424
20455
|
repoRoot: target.repoRoot,
|
|
20425
20456
|
config: target.config
|
|
20426
20457
|
};
|
|
20427
|
-
|
|
20458
|
+
if (!hooked.has(repo.repoRoot)) {
|
|
20459
|
+
hooked.add(repo.repoRoot);
|
|
20460
|
+
await propagateCodexHooks(project.repoRoot, repo.repoRoot);
|
|
20461
|
+
}
|
|
20462
|
+
if (tally.worktree >= MAX_FORK_SWEEP_THREADS2) {
|
|
20463
|
+
tally.deferred++;
|
|
20464
|
+
continue;
|
|
20465
|
+
}
|
|
20466
|
+
tally.worktree++;
|
|
20428
20467
|
const forkPayload = {
|
|
20429
20468
|
session_id: fork.threadId,
|
|
20430
20469
|
cwd: fork.cwd,
|
|
@@ -20508,7 +20547,7 @@ async function sweepCodexForkCaptures(params) {
|
|
|
20508
20547
|
}
|
|
20509
20548
|
appendLog(
|
|
20510
20549
|
"info",
|
|
20511
|
-
`git-traces: fork sweep (parent=${parentSessionId}, event=${event}, triggerRepo=${project.repoRoot}, scannedRollouts=${discovery.scannedRollouts}, forks=${discovery.forks.length}, worktree=${tally.worktree}, sameTree=${tally.sameTree}, unrelated=${tally.unrelated}, initialized=${tally.initialized}, uploaded=${tally.uploaded}, unchanged=${tally.unchanged}, pending=${tally.pending}, failed=${tally.failed}, skipped=${tally.skipped})`
|
|
20550
|
+
`git-traces: fork sweep (parent=${parentSessionId}, event=${event}, triggerRepo=${project.repoRoot}, scannedRollouts=${discovery.scannedRollouts}, forks=${discovery.forks.length}, worktree=${tally.worktree}, sameTree=${tally.sameTree}, unrelated=${tally.unrelated}, initialized=${tally.initialized}, uploaded=${tally.uploaded}, unchanged=${tally.unchanged}, pending=${tally.pending}, failed=${tally.failed}, skipped=${tally.skipped}, deferred=${tally.deferred})`
|
|
20512
20551
|
);
|
|
20513
20552
|
}
|
|
20514
20553
|
async function sweepCodexForksSafely(params) {
|