Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
提交
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,8 +291,12 @@ export class PlatformClient {
/**
* Sends a report_progress event to update the PR title and/or description.
* This triggers the platform to update the pull request associated with the job.
*
* `commitSha` is the SHA of the commit pushed alongside this update, when known.
* Omitted keys are left out of the payload entirely, so servers that do not
* understand a field are unaffected.
*/
async sendReportProgress(options: { prTitle?: string; prDescription?: string }): Promise<SendResult> {
async sendReportProgress(options: { prTitle?: string; prDescription?: string; commitSha?: string }): Promise<SendResult> {
const url = new URL(`jobs/${this._jobId}/progress`, this.baseUrl);
const contentObj: Record<string, string> = {};
if (options.prTitle !== undefined) {
Expand All @@ -301,6 +305,9 @@ export class PlatformClient {
if (options.prDescription !== undefined) {
contentObj.pr_description = options.prDescription;
}
if (options.commitSha !== undefined) {
contentObj.commit_sha = options.commitSha;
}
const payload: ProgressPayload = {
namespace: this.namespace,
kind: "report_progress",
Expand Down
21 changes: 21 additions & 0 deletions src/git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,12 @@ export interface CommitAndPushResult {
hadChanges: boolean;
/** Human-readable message describing the outcome */
message: string;
/**
* SHA of the commit at HEAD after the push succeeded.
* Undefined if the SHA could not be resolved; a successful push is never
* reported as a failure just because this lookup did not work.
*/
commitSha?: string;
}

// =============================================================================
Expand Down Expand Up @@ -301,12 +307,27 @@ export function commitAndPush(repoLocation: string, commitMessage: string): Comm

pushWithRebaseFallback(repoLocation);

// Resolved only after the push succeeded, so the SHA always refers to a commit
// that is actually on the remote. Deliberately isolated in its own try/catch:
// a rev-parse failure must never turn an already-successful push into a
// reported error, which callers could retry into a duplicate commit.
let commitSha: string | undefined;
try {
commitSha = git(["rev-parse", "HEAD"], repoLocation).trim();
} catch (error) {
const msg = error instanceof Error ? error.message : String(error);
// Note: stderr, not stdout — commitAndPush runs inside the stdio MCP
// server (src/mcp-server.ts) where stdout is reserved for the MCP protocol.
console.error(`[Engine SDK] Push succeeded but resolving the commit SHA failed - ${msg}`);
}

return {
success: true,
hadChanges,
message: hadChanges
? `Committed and pushed: ${commitMessage}`
: "No changes to commit. Pushed existing commits.",
commitSha,
};
}

Expand Down
5 changes: 5 additions & 0 deletions src/mcp-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ async function executeReportProgress(
const { commitMessage, prDescription } = input;
const results: string[] = [];
let hasError = false;
// Stays undefined unless a push actually happened and the SHA was resolved,
// so the local-only and error paths never report a SHA that is not on the remote.
let pushedCommitSha: string | undefined;

log("executeReportProgress", { commitMessage, prDescriptionLength: prDescription.length });

Expand All @@ -125,6 +128,7 @@ async function executeReportProgress(
const gitResult = commitAndPush(config.workingDir, commitMessage);
log("git commit and push", { hadChanges: gitResult.hadChanges, message: gitResult.message });
results.push(gitResult.message);
pushedCommitSha = gitResult.commitSha;
} else {
// Local-only mode: just stage and commit without pushing
const { execFileSync } = await import("child_process");
Expand Down Expand Up @@ -160,6 +164,7 @@ async function executeReportProgress(
try {
const sendResult = await config.platformClient.sendReportProgress({
prDescription,
commitSha: pushedCommitSha,
});
if (sendResult.success) {
log("sent report_progress to platform");
Expand Down