feat(FN-3033): align agent asset directory naming and heartbeat path compat

The merge delivers three major features: a droid CLI path reconciliation extension that resolves workspace path mismatches for spawned agents, session-first quick chat with improved heartbeat prompts and a dramatically simplified QuickChatFAB component, and canonical agent asset directory naming wit

Fusion-Task-Id: FN-3033
This commit is contained in:
Fusion
2026-05-01 12:51:23 -07:00
committed by gsxdsm
parent a6ae7b4e04
commit 80b45d0bd5
11 changed files with 392 additions and 36 deletions

View File

@@ -8,6 +8,8 @@ import {
resolveAgentInstructionsWithRatings,
buildAgentChatPrompt,
buildSystemPromptWithInstructions,
ensureDefaultHeartbeatProcedureFile,
resolveAgentHeartbeatProcedure,
} from "../agent-instructions.js";
function makeAgent(overrides: Partial<Agent> = {}): Agent {
@@ -700,3 +702,61 @@ describe("diagnostics logging", () => {
expect(prompt).toContain("## Identity");
});
});
describe("heartbeat procedure path compatibility", () => {
let testDir: string;
beforeEach(async () => {
testDir = await mkdtemp(join(tmpdir(), "agent-heartbeat-proc-"));
});
afterEach(async () => {
await rm(testDir, { recursive: true, force: true });
});
it("loads canonical display-name heartbeat procedure paths", async () => {
const relPath = ".fusion/agents/ceo-agent2736/HEARTBEAT.md";
await mkdir(join(testDir, ".fusion", "agents", "ceo-agent2736"), { recursive: true });
await writeFile(join(testDir, relPath), "Canonical heartbeat", "utf-8");
const content = await resolveAgentHeartbeatProcedure(
makeAgent({ id: "agent2736", heartbeatProcedurePath: relPath }),
testDir,
);
expect(content).toBe("Canonical heartbeat");
});
it("loads legacy id-only heartbeat procedure paths", async () => {
const relPath = ".fusion/agents/agent-legacy/HEARTBEAT.md";
await mkdir(join(testDir, ".fusion", "agents", "agent-legacy"), { recursive: true });
await writeFile(join(testDir, relPath), "Legacy heartbeat", "utf-8");
const content = await resolveAgentHeartbeatProcedure(
makeAgent({ id: "agent-legacy", heartbeatProcedurePath: relPath }),
testDir,
);
expect(content).toBe("Legacy heartbeat");
});
it("rejects traversal heartbeat procedure paths", async () => {
const content = await resolveAgentHeartbeatProcedure(
makeAgent({ heartbeatProcedurePath: "../outside.md" }),
testDir,
);
expect(content).toBeNull();
});
it("seeds default heartbeat procedure only for valid project-relative markdown paths", async () => {
const seeded = await ensureDefaultHeartbeatProcedureFile(
testDir,
".fusion/agents/ceo-agent2736/HEARTBEAT.md",
"Default",
);
expect(seeded).toBeTruthy();
const invalid = await ensureDefaultHeartbeatProcedureFile(testDir, "../outside.md", "Default");
expect(invalid).toBeNull();
});
});