feat(DIS-102): sanitizeForDiscord strips paths and tokens before Discord send #46
2 changed files with 38 additions and 5 deletions
|
|
@ -107,30 +107,43 @@ export async function routeMessage(
|
|||
message.author.username
|
||||
);
|
||||
|
||||
// Sanitize the full response once, then use the sanitized version
|
||||
// for both Discord output and conversation history storage.
|
||||
// This prevents a feedback loop where raw paths in stored history
|
||||
// get fed back to the agent as context, causing it to reproduce them.
|
||||
const sanitizeOpts = {
|
||||
repoRoot: workspace.workspace_path,
|
||||
home: os.homedir(),
|
||||
};
|
||||
const sanitizedResponse = sanitizeForDiscord(response, sanitizeOpts);
|
||||
|
||||
// Split and send response
|
||||
const chunks = splitMessage(response);
|
||||
const chunks = splitMessage(sanitizedResponse);
|
||||
let firstMsgId: string | null = null;
|
||||
|
||||
for (const chunk of chunks) {
|
||||
const sent = await channel.send(sanitizeForDiscord(chunk, { home: os.homedir() }));
|
||||
const sent = await channel.send(chunk);
|
||||
if (!firstMsgId) {
|
||||
firstMsgId = sent.id;
|
||||
}
|
||||
}
|
||||
|
||||
// Store assistant response (use first message id for dedup)
|
||||
// Store sanitized assistant response (use first message id for dedup)
|
||||
if (firstMsgId) {
|
||||
db.addConversation(
|
||||
workspace.id,
|
||||
firstMsgId,
|
||||
"assistant",
|
||||
response,
|
||||
sanitizedResponse,
|
||||
null
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
const msg = error instanceof Error ? error.message : "Unbekannter Fehler";
|
||||
const safeMsg = sanitizeForDiscord(`Fehler bei der Verarbeitung: ${msg}`, { home: os.homedir() });
|
||||
const safeMsg = sanitizeForDiscord(`Fehler bei der Verarbeitung: ${msg}`, {
|
||||
repoRoot: workspace.workspace_path,
|
||||
home: os.homedir(),
|
||||
});
|
||||
await channel.send(safeMsg).catch(() => {});
|
||||
} finally {
|
||||
clearInterval(typingInterval);
|
||||
|
|
|
|||
|
|
@ -64,4 +64,24 @@ describe("sanitizeForDiscord", () => {
|
|||
});
|
||||
expect(result).toBe("<disclaw>/src/index.ts and ~/other.ts");
|
||||
});
|
||||
|
||||
// Windows-style backslash paths are sanitized
|
||||
it("replaces Windows backslash paths", () => {
|
||||
const text = "File at C:\\Users\\dev\\.disclaw\\workspaces\\agent-x\\src\\main.ts";
|
||||
const result = sanitizeForDiscord(text, {
|
||||
repoRoot: "C:\\Users\\dev\\.disclaw\\workspaces\\agent-x",
|
||||
home: "C:\\Users\\dev",
|
||||
});
|
||||
expect(result).toBe("File at <disclaw>\\src\\main.ts");
|
||||
});
|
||||
|
||||
// Mixed slash styles (common on Windows when tools output forward slashes)
|
||||
it("replaces forward-slash variants of Windows paths", () => {
|
||||
const text = "File at C:/Users/dev/.disclaw/workspaces/agent-x/src/main.ts";
|
||||
const result = sanitizeForDiscord(text, {
|
||||
repoRoot: "C:\\Users\\dev\\.disclaw\\workspaces\\agent-x",
|
||||
home: "C:\\Users\\dev",
|
||||
});
|
||||
expect(result).toBe("File at <disclaw>/src/main.ts");
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue