feat(KB-336): rename data directory from .kb to .fusion

- Rename data directory from .kb to .fusion across core, CLI, dashboard, and engine
- Update all path references in source files, tests, and CLI output
- Remove deprecated central-core infrastructure (central-core, central-db, central-integration)
- Remove obsolete test files (PlanningModeModal.test.tsx, ScheduleForm.test.tsx)
- Add changeset for the directory rename breaking change
This commit is contained in:
gsxdsm
2026-03-31 20:00:25 -07:00
parent 1937adc7be
commit 57f34d1937
28 changed files with 116 additions and 108 deletions

View File

@@ -1391,7 +1391,7 @@ describe("buildExecutionPrompt", () => {
expect(result).toContain("## Attachments");
expect(result).toContain("**screenshot.png** (screenshot)");
expect(result).toContain("/home/user/project/.kb/tasks/KB-001/attachments/abc123-screenshot.png");
expect(result).toContain("/home/user/project/.fusion/tasks/KB-001/attachments/abc123-screenshot.png");
});
it("includes attachment section with absolute paths for text attachments", () => {
@@ -1405,7 +1405,7 @@ describe("buildExecutionPrompt", () => {
expect(result).toContain("## Attachments");
expect(result).toContain("**error.log** (text/plain)");
expect(result).toContain("read for context");
expect(result).toContain("/home/user/project/.kb/tasks/KB-001/attachments/def456-error.log");
expect(result).toContain("/home/user/project/.fusion/tasks/KB-001/attachments/def456-error.log");
});
it("includes both image and text attachments", () => {

View File

@@ -1677,7 +1677,7 @@ git log --oneline
const IMAGE_MIMES = new Set(["image/png", "image/jpeg", "image/gif", "image/webp"]);
const lines = ["## Attachments", ""];
for (const att of task.attachments) {
const absPath = `${rootDir}/.kb/tasks/${task.id}/attachments/${att.filename}`;
const absPath = `${rootDir}/.fusion/tasks/${task.id}/attachments/${att.filename}`;
if (IMAGE_MIMES.has(att.mimeType)) {
lines.push(`- **${att.originalName}** (screenshot): \`${absPath}\``);
} else {

View File

@@ -173,7 +173,7 @@ export class Scheduler {
* @returns Object with `valid: true` if checks pass, or `valid: false` with a `reason` string if they fail
*/
private async validateTaskFilesystem(id: string): Promise<{ valid: boolean; reason?: string }> {
const taskDir = join(this.store.getRootDir(), ".kb", "tasks", id);
const taskDir = join(this.store.getRootDir(), ".fusion", "tasks", id);
// Check if task directory exists
if (!existsSync(taskDir)) {

View File

@@ -63,14 +63,14 @@ describe("buildSpecificationPrompt", () => {
it("generates basic specification prompt", () => {
const prompt = buildSpecificationPrompt(
baseTask,
".kb/tasks/KB-001/PROMPT.md",
".fusion/tasks/KB-001/PROMPT.md",
);
expect(prompt).toContain("Specify this task");
expect(prompt).toContain("FN-001");
expect(prompt).toContain("Test Task");
expect(prompt).toContain("Test task description");
expect(prompt).toContain(".kb/tasks/KB-001/PROMPT.md");
expect(prompt).toContain(".fusion/tasks/KB-001/PROMPT.md");
});
it("includes project commands when provided", () => {
@@ -86,7 +86,7 @@ describe("buildSpecificationPrompt", () => {
const prompt = buildSpecificationPrompt(
baseTask,
".kb/tasks/KB-001/PROMPT.md",
".fusion/tasks/KB-001/PROMPT.md",
settings,
);
@@ -101,7 +101,7 @@ describe("buildSpecificationPrompt", () => {
const prompt = buildSpecificationPrompt(
baseTask,
".kb/tasks/KB-001/PROMPT.md",
".fusion/tasks/KB-001/PROMPT.md",
undefined,
[],
existingPrompt,
@@ -133,7 +133,7 @@ describe("buildSpecificationPrompt", () => {
const prompt = buildSpecificationPrompt(
baseTask,
".kb/tasks/KB-001/PROMPT.md",
".fusion/tasks/KB-001/PROMPT.md",
undefined,
attachments,
);
@@ -152,7 +152,7 @@ describe("buildSpecificationPrompt", () => {
const prompt = buildSpecificationPrompt(
taskWithDeps,
".kb/tasks/KB-001/PROMPT.md",
".fusion/tasks/KB-001/PROMPT.md",
);
expect(prompt).toContain("Dependencies");
@@ -167,7 +167,7 @@ describe("buildSpecificationPrompt", () => {
const prompt = buildSpecificationPrompt(
taskWithoutTitle,
".kb/tasks/KB-001/PROMPT.md",
".fusion/tasks/KB-001/PROMPT.md",
);
expect(prompt).toContain("(none)");
@@ -176,7 +176,7 @@ describe("buildSpecificationPrompt", () => {
it("includes proactive subtask guidance when breakdown was not explicitly requested", () => {
const prompt = buildSpecificationPrompt(
baseTask,
".kb/tasks/KB-001/PROMPT.md",
".fusion/tasks/KB-001/PROMPT.md",
);
expect(prompt).toContain("## Subtask Consideration");
@@ -191,7 +191,7 @@ describe("buildSpecificationPrompt", () => {
...baseTask,
breakIntoSubtasks: true,
},
".kb/tasks/KB-001/PROMPT.md",
".fusion/tasks/KB-001/PROMPT.md",
);
expect(prompt).toContain("## Subtask Breakdown Requested");
@@ -221,7 +221,7 @@ describe("readAttachmentContents", () => {
beforeEach(async () => {
// Clean up and create test directory
await rm(testDir, { recursive: true, force: true });
await mkdir(join(testDir, ".kb", "tasks", taskId, "attachments"), {
await mkdir(join(testDir, ".fusion", "tasks", taskId, "attachments"), {
recursive: true,
});
});
@@ -253,7 +253,7 @@ describe("readAttachmentContents", () => {
const content = "Test notes content";
await writeFile(
join(testDir, ".kb", "tasks", taskId, "attachments", "1234567890-notes.txt"),
join(testDir, ".fusion", "tasks", taskId, "attachments", "1234567890-notes.txt"),
content,
);
@@ -278,7 +278,7 @@ describe("readAttachmentContents", () => {
const largeContent = "a".repeat(60 * 1024); // 60KB
await writeFile(
join(testDir, ".kb", "tasks", taskId, "attachments", "1234567890-large.txt"),
join(testDir, ".fusion", "tasks", taskId, "attachments", "1234567890-large.txt"),
largeContent,
);
@@ -302,7 +302,7 @@ describe("readAttachmentContents", () => {
// Write fake PNG data (just some bytes)
const imageData = Buffer.from([0x89, 0x50, 0x4e, 0x47]); // PNG magic bytes
await writeFile(
join(testDir, ".kb", "tasks", taskId, "attachments", "1234567890-image.png"),
join(testDir, ".fusion", "tasks", taskId, "attachments", "1234567890-image.png"),
imageData,
);
@@ -444,7 +444,7 @@ describe("requirePlanApproval setting", () => {
});
it("sets awaiting-approval status instead of moving to todo when requirePlanApproval is true", async () => {
const taskDir = join(rootDir, ".kb", "tasks", "FN-001");
const taskDir = join(rootDir, ".fusion", "tasks", "FN-001");
await mkdir(taskDir, { recursive: true });
await writeFile(
join(taskDir, "task.json"),

View File

@@ -410,7 +410,7 @@ export class TriageProcessor {
try {
const detail = await this.store.getTask(task.id);
const settings = await this.store.getSettings();
const promptPath = `.kb/tasks/${task.id}/PROMPT.md`;
const promptPath = `.fusion/tasks/${task.id}/PROMPT.md`;
const agentWork = async () => {
// Set status only after the semaphore slot has been acquired, so
@@ -1056,7 +1056,7 @@ export async function readAttachmentContents(
for (const att of attachments) {
const filePath = join(
rootDir,
".kb",
".fusion",
"tasks",
taskId,
"attachments",