Fix conference room chat crashes: duplicate message IDs, empty bubbles, and untrusted directory

Three bugs fixed:
1. Deduplicate run messages when same run appears in both linkedRuns and liveRuns
   during transition, preventing assistant-ui MessageRepository crash.
2. Render waitingText as content in live run messages so empty transcript
   doesn't produce an empty chat bubble.
3. Auto-initialize git repo in agent home directories so Claude Code doesn't
   reject the workspace as untrusted.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-04-30 16:28:59 -05:00
1 parent 1b54120faf
commit 37f9e3b6d6
2 files changed
+21 -1

No files matched your search

@@ -1,3 +1,4 @@
import { execFile } from "node:child_process";
import fs from "node:fs/promises";
import path from "node:path";
import { fileURLToPath } from "node:url";
@@ -56,6 +57,16 @@ import { prepareClaudePromptBundle } from "./prompt-cache.js";
const __moduleDir = path.dirname(fileURLToPath(import.meta.url));
async function ensureGitRepo(dir: string): Promise<void> {
try {
await fs.access(path.join(dir, ".git"));
} catch {
await new Promise<void>((resolve, reject) => {
execFile("git", ["init"], { cwd: dir }, (err) => (err ? reject(err) : resolve()));
});
}
}
interface ClaudeExecutionInput {
runId: string;
agent: AdapterExecutionContext["agent"];
@@ -146,6 +157,9 @@ async function buildClaudeRuntimeConfig(input: ClaudeExecutionInput): Promise<Cl
const effectiveWorkspaceCwd = useConfiguredInsteadOfAgentHome ? "" : workspaceCwd;
const cwd = effectiveWorkspaceCwd || configuredCwd || process.cwd();
await ensureAbsoluteDirectory(cwd, { createIfMissing: true });
if (workspaceSource === "agent_home" || (!effectiveWorkspaceCwd && !configuredCwd)) {
await ensureGitRepo(cwd);
}
const envConfig = parseObject(config.env);
const hasExplicitApiKey =
+7 -1
View File
@@ -747,7 +747,11 @@ function createLiveRunMessage(args: {
? ""
: "Working...";
const content = parts;
const content: typeof parts = parts.length > 0
? parts
: waitingText
? [{ type: "text", text: waitingText }]
: [];
const message: ThreadAssistantMessage = {
id: `run-assistant:${run.id}`,
@@ -859,7 +863,9 @@ export function buildIssueChatMessages(args: {
});
}
const linkedRunIds = new Set(linkedRuns.map((r) => r.runId));
for (const run of normalizeLiveRuns(liveRuns, activeRun, issueId)) {
if (linkedRunIds.has(run.id)) continue;
orderedMessages.push({
createdAtMs: toTimestamp(run.startedAt ?? run.createdAt),
order: 3,