feat: universalize observation feed emojis (#1100)
* feat: universalize observation feed emojis with config-driven system Replace hardcoded AGENT_EMOJI_MAP with a three-tier approach: 1. User-pinned emojis via observationFeed.emojis.agents config 2. Deterministic auto-assign from pool using agentId hash 3. Configurable fallbacks for primary, Claude Code, and default emojis Claude Code sessions now display "Claude Code Session" instead of the working directory name. All emoji settings are exposed in the plugin configSchema so the onboarding wizard AI can discover and configure them. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(feed): keep Claude Code project id in source labels --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -841,6 +841,77 @@ describe("SSE stream integration", () => {
|
||||
await getService().stop({});
|
||||
});
|
||||
|
||||
it("includes Claude Code project identifier in source label", async () => {
|
||||
const { api, sentMessages, getService } = createMockApi({
|
||||
workerPort: serverPort,
|
||||
observationFeed: { enabled: true, channel: "telegram", to: "12345" },
|
||||
});
|
||||
claudeMemPlugin(api);
|
||||
|
||||
await getService().start({});
|
||||
await new Promise((resolve) => setTimeout(resolve, 200));
|
||||
|
||||
const observation = {
|
||||
type: "new_observation",
|
||||
observation: {
|
||||
id: 11,
|
||||
title: "Project Label",
|
||||
subtitle: "Check source label",
|
||||
project: "workspace-alpha",
|
||||
},
|
||||
timestamp: Date.now(),
|
||||
};
|
||||
|
||||
for (const res of serverResponses) {
|
||||
res.write(`data: ${JSON.stringify(observation)}\n\n`);
|
||||
}
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 200));
|
||||
|
||||
assert.equal(sentMessages.length, 1);
|
||||
assert.ok(sentMessages[0].text.includes("Claude Code Session (workspace-alpha)"));
|
||||
|
||||
await getService().stop({});
|
||||
});
|
||||
|
||||
it("uses custom Claude Code label prefix while preserving project identifier", async () => {
|
||||
const { api, sentMessages, getService } = createMockApi({
|
||||
workerPort: serverPort,
|
||||
observationFeed: {
|
||||
enabled: true,
|
||||
channel: "telegram",
|
||||
to: "12345",
|
||||
emojis: { claudeCodeLabel: "Coding Session" },
|
||||
},
|
||||
});
|
||||
claudeMemPlugin(api);
|
||||
|
||||
await getService().start({});
|
||||
await new Promise((resolve) => setTimeout(resolve, 200));
|
||||
|
||||
const observation = {
|
||||
type: "new_observation",
|
||||
observation: {
|
||||
id: 12,
|
||||
title: "Custom Label",
|
||||
subtitle: "Custom prefix",
|
||||
project: "workspace-beta",
|
||||
},
|
||||
timestamp: Date.now(),
|
||||
};
|
||||
|
||||
for (const res of serverResponses) {
|
||||
res.write(`data: ${JSON.stringify(observation)}\n\n`);
|
||||
}
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 200));
|
||||
|
||||
assert.equal(sentMessages.length, 1);
|
||||
assert.ok(sentMessages[0].text.includes("Coding Session (workspace-beta)"));
|
||||
|
||||
await getService().stop({});
|
||||
});
|
||||
|
||||
it("filters out non-observation events", async () => {
|
||||
const { api, sentMessages, getService } = createMockApi({
|
||||
workerPort: serverPort,
|
||||
|
||||
Reference in New Issue
Block a user