fix(engine): give merge commits a real subject in fallback paths

Three merger fallback commit paths (auto-resolve-all-conflicts,
-X theirs/ours side strategy, AI-agent-didn't-commit) hard-coded
`feat(FN-XXXX): merge fusion/fn-xxxx` as the subject and never used
the AI subject summarizer. Route them through buildDeterministicMergeMessage
so they pick up aiSubject when available.

When the AI subject summarizer returns null, derive the subject from
the branch's first step commit (with conventional-commit prefix
stripped, plus `(+N more)` for multi-commit branches) instead of the
bare `merge <branch>` template.

Bump DEFAULT_COMMIT_SUBJECT_TIMEOUT_MS 15s → 30s so slow-first-token
providers complete instead of silently falling back.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsxdsm
2026-05-02 13:32:47 -07:00
parent 174453465f
commit df04acd4e2
4 changed files with 92 additions and 18 deletions

View File

@@ -1489,8 +1489,13 @@ describe("aiMergeTask — includeTaskIdInCommit setting", () => {
(call) => String(call[0]).includes("git commit"),
);
expect(commitCall).toBeDefined();
expect(String(commitCall![0])).toContain("feat: merge");
// Subject must use bare `feat:` prefix (no task-id scope) when
// includeTaskIdInCommit=false. The summary portion is derived from the
// step commit log or AI subject, so we don't pin its exact text — just
// assert the prefix shape.
expect(String(commitCall![0])).toMatch(/git commit -m "feat: \S/);
expect(String(commitCall![0])).not.toContain("feat(KB-050)");
expect(String(commitCall![0])).not.toContain("feat(FN-050)");
});
});