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 5ae3b1e891
commit 80ab88db3d
28 changed files with 116 additions and 108 deletions

View File

@@ -32,7 +32,7 @@ describe("TaskStore.listTasks() sort order", () => {
// Force identical createdAt by rewriting the task.json files
const { readFile, writeFile } = await import("node:fs/promises");
const tasksDir = join(rootDir, ".kb", "tasks");
const tasksDir = join(rootDir, ".fusion", "tasks");
const sameTimestamp = "2026-06-01T00:00:00Z";
for (const t of [t1, t2, t3]) {

View File

@@ -84,7 +84,7 @@ export class AgentStore extends EventEmitter {
constructor(options: AgentStoreOptions = {}) {
super();
this.rootDir = options.rootDir ?? ".kb";
this.rootDir = options.rootDir ?? ".fusion";
this.agentsDir = join(this.rootDir, "agents");
}

View File

@@ -40,14 +40,14 @@ describe("AutomationStore", () => {
describe("init", () => {
it("creates the automations directory", async () => {
const dir = join(rootDir, ".kb", "automations");
const dir = join(rootDir, ".fusion", "automations");
expect(existsSync(dir)).toBe(true);
});
it("is idempotent", async () => {
await store.init();
await store.init();
const dir = join(rootDir, ".kb", "automations");
const dir = join(rootDir, ".fusion", "automations");
expect(existsSync(dir)).toBe(true);
});
});
@@ -182,7 +182,7 @@ describe("AutomationStore", () => {
scheduleType: "weekly",
});
const filePath = join(rootDir, ".kb", "automations", `${schedule.id}.json`);
const filePath = join(rootDir, ".fusion", "automations", `${schedule.id}.json`);
expect(existsSync(filePath)).toBe(true);
});
@@ -364,7 +364,7 @@ describe("AutomationStore", () => {
const deleted = await store.deleteSchedule(schedule.id);
expect(deleted.id).toBe(schedule.id);
const filePath = join(rootDir, ".kb", "automations", `${schedule.id}.json`);
const filePath = join(rootDir, ".fusion", "automations", `${schedule.id}.json`);
expect(existsSync(filePath)).toBe(false);
});

View File

@@ -30,7 +30,7 @@ export class AutomationStore extends EventEmitter<AutomationStoreEvents> {
constructor(private rootDir: string) {
super();
this.automationsDir = join(rootDir, ".kb", "automations");
this.automationsDir = join(rootDir, ".fusion", "automations");
}
/**
@@ -38,7 +38,7 @@ export class AutomationStore extends EventEmitter<AutomationStoreEvents> {
*/
private get db(): Database {
if (!this._db) {
const kbDir = join(this.rootDir, ".kb");
const kbDir = join(this.rootDir, ".fusion");
this._db = new Database(kbDir);
this._db.init();
}

View File

@@ -26,7 +26,7 @@ describe("BackupManager", () => {
beforeEach(async () => {
tempDir = mkdtempSync(join(tmpdir(), "kb-backup-test-"));
kbDir = join(tempDir, ".kb");
kbDir = join(tempDir, ".fusion");
await mkdir(kbDir, { recursive: true });
// Create a dummy database file
writeFileSync(join(kbDir, "kb.db"), "dummy database content");
@@ -103,7 +103,7 @@ describe("BackupManager", () => {
await backupManager.createBackup();
// Create some non-backup files
const backupDir = join(tempDir, ".kb/backups");
const backupDir = join(tempDir, ".fusion/backups");
await writeFile(join(backupDir, "not-a-backup.txt"), "content");
await writeFile(join(backupDir, "random.db"), "content");
@@ -265,7 +265,7 @@ describe("validateBackupRetention", () => {
describe("validateBackupDir", () => {
it("should return true for valid relative paths", () => {
expect(validateBackupDir(".kb/backups")).toBe(true);
expect(validateBackupDir(".fusion/backups")).toBe(true);
expect(validateBackupDir("backups")).toBe(true);
expect(validateBackupDir("data/backups/kb")).toBe(true);
});
@@ -277,7 +277,7 @@ describe("validateBackupDir", () => {
it("should return false for paths with parent traversal", () => {
expect(validateBackupDir("../backups")).toBe(false);
expect(validateBackupDir(".kb/../backups")).toBe(false);
expect(validateBackupDir(".fusion/../backups")).toBe(false);
expect(validateBackupDir("data/../../backups")).toBe(false);
});
@@ -289,13 +289,13 @@ describe("validateBackupDir", () => {
describe("createBackupManager", () => {
it("should create manager with default options when no settings provided", () => {
const manager = createBackupManager("/tmp/.kb");
const manager = createBackupManager("/tmp/.fusion");
expect(manager).toBeInstanceOf(BackupManager);
});
it("should use settings when provided", async () => {
const tempDir = mkdtempSync(join(tmpdir(), "kb-backup-test-"));
const kbDir = join(tempDir, ".kb");
const kbDir = join(tempDir, ".fusion");
await mkdir(kbDir, { recursive: true });
writeFileSync(join(kbDir, "kb.db"), "test");
@@ -326,7 +326,7 @@ describe("runBackupCommand", () => {
beforeEach(async () => {
tempDir = mkdtempSync(join(tmpdir(), "kb-backup-test-"));
kbDir = join(tempDir, ".kb");
kbDir = join(tempDir, ".fusion");
await mkdir(kbDir, { recursive: true });
writeFileSync(join(kbDir, "kb.db"), "dummy database content");
});

View File

@@ -22,7 +22,7 @@ export interface BackupInfo {
* Options for configuring the backup manager.
*/
export interface BackupOptions {
/** Directory for backup files, relative to the project root. Default: ".kb/backups" */
/** Directory for backup files, relative to the project root. Default: ".fusion/backups" */
backupDir?: string;
/** Number of backups to retain. Default: 7 */
retention?: number;
@@ -44,7 +44,7 @@ export class BackupManager {
*/
constructor(kbDir: string, options?: BackupOptions) {
this.kbDir = kbDir;
this.backupDir = options?.backupDir ?? ".kb/backups";
this.backupDir = options?.backupDir ?? ".fusion/backups";
this.retention = options?.retention ?? 7;
}

View File

@@ -16,7 +16,7 @@ describe("detectLegacyData", () => {
beforeEach(() => {
tmpDir = makeTmpDir();
kbDir = join(tmpDir, ".kb");
kbDir = join(tmpDir, ".fusion");
});
afterEach(async () => {
@@ -77,7 +77,7 @@ describe("getMigrationStatus", () => {
beforeEach(() => {
tmpDir = makeTmpDir();
kbDir = join(tmpDir, ".kb");
kbDir = join(tmpDir, ".fusion");
});
afterEach(async () => {
@@ -121,7 +121,7 @@ describe("migrateFromLegacy", () => {
beforeEach(async () => {
tmpDir = makeTmpDir();
kbDir = join(tmpDir, ".kb");
kbDir = join(tmpDir, ".fusion");
await mkdir(kbDir, { recursive: true });
db = new Database(kbDir);
db.init();

View File

@@ -1,7 +1,7 @@
/**
* Migration from legacy file-based storage to SQLite.
*
* Detects legacy data (.kb/tasks/, .kb/config.json, etc.) and migrates
* Detects legacy data (.fusion/tasks/, .fusion/config.json, etc.) and migrates
* it to the SQLite database. After successful migration, original files
* are renamed with .bak suffix as backups.
*
@@ -443,7 +443,7 @@ async function migrateAgents(kbDir: string, db: Database): Promise<void> {
/**
* Create backups of legacy files by renaming them with .bak suffix.
* Note: .kb/tasks/ is NOT renamed because blob files (PROMPT.md, agent.log,
* Note: .fusion/tasks/ is NOT renamed because blob files (PROMPT.md, agent.log,
* attachments) remain on the filesystem. Only task.json files inside each
* task directory are the "migrated" data now in SQLite. We rename individual
* task.json files to task.json.bak instead.

View File

@@ -17,7 +17,7 @@ describe("Database", () => {
beforeEach(() => {
tmpDir = makeTmpDir();
kbDir = join(tmpDir, ".kb");
kbDir = join(tmpDir, ".fusion");
db = new Database(kbDir);
db.init(); // Explicit init required — createDatabase() does not auto-init
});
@@ -36,7 +36,7 @@ describe("Database", () => {
expect(existsSync(join(kbDir, "kb.db"))).toBe(true);
});
it("creates the .kb directory if missing", () => {
it("creates the .fusion directory if missing", () => {
expect(existsSync(kbDir)).toBe(true);
});
@@ -598,7 +598,7 @@ describe("schema migrations", () => {
it("migrates a v1 database by adding missing columns", () => {
tmpDir = makeTmpDir();
const kbDir = join(tmpDir, ".kb");
const kbDir = join(tmpDir, ".fusion");
// Create a v1 database manually (without comments and mergeDetails columns)
const db = new Database(kbDir);
@@ -705,7 +705,7 @@ describe("schema migrations", () => {
it("skips migration if already at target version", () => {
tmpDir = makeTmpDir();
const kbDir = join(tmpDir, ".kb");
const kbDir = join(tmpDir, ".fusion");
const db = new Database(kbDir);
db.init();
@@ -720,7 +720,7 @@ describe("schema migrations", () => {
it("migrates a v2 database by adding missionId and sliceId columns", () => {
tmpDir = makeTmpDir();
const kbDir = join(tmpDir, ".kb");
const kbDir = join(tmpDir, ".fusion");
// Create a v2 database manually (without missionId and sliceId columns)
const db = new Database(kbDir);
@@ -847,7 +847,7 @@ describe("createDatabase factory", () => {
it("creates a database instance without auto-init", () => {
tmpDir = makeTmpDir();
const kbDir = join(tmpDir, ".kb");
const kbDir = join(tmpDir, ".fusion");
const db = createDatabase(kbDir);
// DB file exists (created on open) but schema not initialized
@@ -860,7 +860,7 @@ describe("createDatabase factory", () => {
it("works after explicit init()", () => {
tmpDir = makeTmpDir();
const kbDir = join(tmpDir, ".kb");
const kbDir = join(tmpDir, ".fusion");
const db = createDatabase(kbDir);
db.init();
@@ -872,7 +872,7 @@ describe("createDatabase factory", () => {
it("getPath returns the database file path", () => {
tmpDir = makeTmpDir();
const kbDir = join(tmpDir, ".kb");
const kbDir = join(tmpDir, ".fusion");
const db = createDatabase(kbDir);
expect(db.getPath()).toBe(join(kbDir, "kb.db"));
@@ -882,7 +882,7 @@ describe("createDatabase factory", () => {
it("is idempotent when init() called multiple times", () => {
tmpDir = makeTmpDir();
const kbDir = join(tmpDir, ".kb");
const kbDir = join(tmpDir, ".fusion");
// First call
const db1 = createDatabase(kbDir);

View File

@@ -253,7 +253,7 @@ export class Database {
constructor(private kbDir: string) {
this.dbPath = join(kbDir, "kb.db");
// Ensure .kb directory exists
// Ensure .fusion directory exists
if (!existsSync(kbDir)) {
mkdirSync(kbDir, { recursive: true });
}
@@ -466,7 +466,7 @@ export class Database {
/**
* Create a new Database instance (does NOT initialize schema).
* Callers must call `db.init()` separately.
* @param kbDir - Path to the `.kb` directory (e.g., `/path/to/project/.kb`)
* @param kbDir - Path to the `.fusion` directory (e.g., `/path/to/project/.fusion`)
* @returns Database instance (not yet initialized)
*/
export function createDatabase(kbDir: string): Database {

View File

@@ -30,7 +30,7 @@ describe("MissionStore", () => {
beforeEach(() => {
tmpDir = makeTmpDir();
kbDir = join(tmpDir, ".kb");
kbDir = join(tmpDir, ".fusion");
db = new Database(kbDir);
db.init();
store = new MissionStore(kbDir, db);

View File

@@ -20,7 +20,7 @@ import {
// Helper to create a temporary test environment
function createTestEnv() {
const tempDir = mkdtempSync(join(tmpdir(), "kb-settings-test-"));
const kbDir = join(tempDir, ".kb");
const kbDir = join(tempDir, ".fusion");
const tasksDir = join(kbDir, "tasks");
const globalSettingsDir = join(tempDir, "global-settings");

View File

@@ -35,7 +35,7 @@ describe("TaskStore", () => {
async function createTaskWithSteps(): Promise<Task> {
const task = await store.createTask({ description: "Task with steps" });
// Write a PROMPT.md with steps so updateStep works
const dir = join(rootDir, ".kb", "tasks", task.id);
const dir = join(rootDir, ".fusion", "tasks", task.id);
await writeFile(
join(dir, "PROMPT.md"),
`# ${task.id}: Task with steps
@@ -59,7 +59,7 @@ describe("TaskStore", () => {
}
async function deleteTaskDir(taskId: string): Promise<string> {
const dir = join(rootDir, ".kb", "tasks", taskId);
const dir = join(rootDir, ".fusion", "tasks", taskId);
await rm(dir, { recursive: true, force: true });
return dir;
}
@@ -174,7 +174,7 @@ describe("TaskStore", () => {
await Promise.all(promises);
// Read back and verify valid JSON
const taskJsonPath = join(rootDir, ".kb", "tasks", id, "task.json");
const taskJsonPath = join(rootDir, ".fusion", "tasks", id, "task.json");
const raw = await readFile(taskJsonPath, "utf-8");
const result = JSON.parse(raw) as Task;
@@ -189,7 +189,7 @@ describe("TaskStore", () => {
describe("defensive JSON parsing", () => {
it("reads from SQLite even if task.json on disk is corrupted", async () => {
const task = await createTestTask();
const taskJsonPath = join(rootDir, ".kb", "tasks", task.id, "task.json");
const taskJsonPath = join(rootDir, ".fusion", "tasks", task.id, "task.json");
// Corrupt the file: append duplicate trailing content
const validJson = await readFile(taskJsonPath, "utf-8");
@@ -203,7 +203,7 @@ describe("TaskStore", () => {
it("reads from SQLite even if task.json contains invalid content", async () => {
const task = await createTestTask();
const taskJsonPath = join(rootDir, ".kb", "tasks", task.id, "task.json");
const taskJsonPath = join(rootDir, ".fusion", "tasks", task.id, "task.json");
// Write completely invalid content
await writeFile(taskJsonPath, "not json at all {{{");
@@ -219,7 +219,7 @@ describe("TaskStore", () => {
describe("atomic writes", () => {
it("produces valid JSON after write with no .tmp files left behind", async () => {
const task = await createTestTask();
const dir = join(rootDir, ".kb", "tasks", task.id);
const dir = join(rootDir, ".fusion", "tasks", task.id);
// Perform a write
await store.logEntry(task.id, "atomic test");
@@ -253,13 +253,13 @@ describe("TaskStore", () => {
expect(sortedIds).toEqual(["FN-001", "FN-002", "FN-003", "FN-004", "FN-005"]);
// config.json should be valid JSON with nextId = 6
const configPath = join(rootDir, ".kb", "config.json");
const configPath = join(rootDir, ".fusion", "config.json");
const raw = await readFile(configPath, "utf-8");
const config = JSON.parse(raw);
expect(config.nextId).toBe(6);
// No .tmp files left behind
const haiDir = join(rootDir, ".kb");
const haiDir = join(rootDir, ".fusion");
const files = await readdir(haiDir);
expect(files.filter((f) => f.endsWith(".tmp"))).toHaveLength(0);
});
@@ -288,7 +288,7 @@ describe("TaskStore", () => {
expect(updated.attachments![0].filename).toBe(attachment.filename);
// Verify file on disk
const filePath = join(rootDir, ".kb", "tasks", task.id, "attachments", attachment.filename);
const filePath = join(rootDir, ".fusion", "tasks", task.id, "attachments", attachment.filename);
const content = await readFile(filePath);
expect(content).toEqual(TINY_PNG);
});
@@ -344,7 +344,7 @@ describe("TaskStore", () => {
expect(updated.attachments).toBeUndefined();
// Verify file removed from disk
const filePath = join(rootDir, ".kb", "tasks", task.id, "attachments", attachment.filename);
const filePath = join(rootDir, ".fusion", "tasks", task.id, "attachments", attachment.filename);
expect(existsSync(filePath)).toBe(false);
});
@@ -452,7 +452,7 @@ describe("TaskStore", () => {
expect(settings.themeMode).toBe("dark");
// Verify the project config doesn't contain themeMode
const configRaw = await readFile(join(rootDir, ".kb", "config.json"), "utf-8");
const configRaw = await readFile(join(rootDir, ".fusion", "config.json"), "utf-8");
const config = JSON.parse(configRaw);
expect(config.settings.themeMode).toBeUndefined();
});
@@ -840,7 +840,7 @@ describe("TaskStore", () => {
it("updateStep recreates missing task directory and persists regenerated task.json", async () => {
const task = await createTaskWithSteps();
const promptDir = join(rootDir, ".kb", "tasks", task.id);
const promptDir = join(rootDir, ".fusion", "tasks", task.id);
const prompt = await readFile(join(promptDir, "PROMPT.md"), "utf-8");
const dir = await deleteTaskDir(task.id);
await mkdir(dir, { recursive: true });
@@ -919,7 +919,7 @@ describe("TaskStore", () => {
const task = await createTestTask();
const duplicate = await store.duplicateTask(task.id);
const duplicateDir = join(rootDir, ".kb", "tasks", duplicate.id);
const duplicateDir = join(rootDir, ".fusion", "tasks", duplicate.id);
expect(existsSync(duplicateDir)).toBe(true);
expect(existsSync(join(duplicateDir, "PROMPT.md"))).toBe(true);
@@ -1703,7 +1703,7 @@ describe("TaskStore", () => {
await Promise.all(promises);
// Read back and verify valid JSON
const taskJsonPath = join(rootDir, ".kb", "tasks", task.id, "task.json");
const taskJsonPath = join(rootDir, ".fusion", "tasks", task.id, "task.json");
const raw = await readFile(taskJsonPath, "utf-8");
const result = JSON.parse(raw) as Task;
@@ -1731,7 +1731,7 @@ describe("TaskStore", () => {
describe("parseDependenciesFromPrompt", () => {
it("returns single dependency from PROMPT.md", async () => {
const task = await store.createTask({ description: "Task with dep" });
const dir = join(rootDir, ".kb", "tasks", task.id);
const dir = join(rootDir, ".fusion", "tasks", task.id);
await writeFile(
join(dir, "PROMPT.md"),
`# ${task.id}: Task with dep
@@ -1753,7 +1753,7 @@ describe("TaskStore", () => {
it("returns multiple dependencies in order", async () => {
const task = await store.createTask({ description: "Task with deps" });
const dir = join(rootDir, ".kb", "tasks", task.id);
const dir = join(rootDir, ".fusion", "tasks", task.id);
await writeFile(
join(dir, "PROMPT.md"),
`# ${task.id}: Task with deps
@@ -1777,7 +1777,7 @@ describe("TaskStore", () => {
it("returns empty array when dependencies section says None", async () => {
const task = await store.createTask({ description: "No deps" });
const dir = join(rootDir, ".kb", "tasks", task.id);
const dir = join(rootDir, ".fusion", "tasks", task.id);
await writeFile(
join(dir, "PROMPT.md"),
`# ${task.id}: No deps
@@ -1799,7 +1799,7 @@ describe("TaskStore", () => {
it("returns empty array when no Dependencies section exists", async () => {
const task = await store.createTask({ description: "No section" });
const dir = join(rootDir, ".kb", "tasks", task.id);
const dir = join(rootDir, ".fusion", "tasks", task.id);
await writeFile(
join(dir, "PROMPT.md"),
`# ${task.id}: No section
@@ -1817,7 +1817,7 @@ describe("TaskStore", () => {
it("returns empty array when task has no PROMPT.md file", async () => {
const task = await store.createTask({ description: "No prompt" });
const dir = join(rootDir, ".kb", "tasks", task.id);
const dir = join(rootDir, ".fusion", "tasks", task.id);
// Delete the PROMPT.md that createTask generates
await unlink(join(dir, "PROMPT.md"));
@@ -1837,7 +1837,7 @@ describe("TaskStore", () => {
describe("parseFileScopeFromPrompt", () => {
it("returns paths when File Scope is followed by another heading", async () => {
const task = await store.createTask({ description: "Mid-file scope" });
const dir = join(rootDir, ".kb", "tasks", task.id);
const dir = join(rootDir, ".fusion", "tasks", task.id);
await writeFile(
join(dir, "PROMPT.md"),
`# ${task.id}: Mid-file scope
@@ -1865,7 +1865,7 @@ describe("TaskStore", () => {
const task = await store.createTask({
description: "End-of-file scope",
});
const dir = join(rootDir, ".kb", "tasks", task.id);
const dir = join(rootDir, ".fusion", "tasks", task.id);
await writeFile(
join(dir, "PROMPT.md"),
`# ${task.id}: End-of-file scope
@@ -1893,7 +1893,7 @@ describe("TaskStore", () => {
it("returns empty array when no File Scope section exists", async () => {
const task = await store.createTask({ description: "No scope" });
const dir = join(rootDir, ".kb", "tasks", task.id);
const dir = join(rootDir, ".fusion", "tasks", task.id);
await writeFile(
join(dir, "PROMPT.md"),
`# ${task.id}: No scope
@@ -1911,7 +1911,7 @@ describe("TaskStore", () => {
it("returns empty array when PROMPT.md does not exist", async () => {
const task = await store.createTask({ description: "No prompt" });
const dir = join(rootDir, ".kb", "tasks", task.id);
const dir = join(rootDir, ".fusion", "tasks", task.id);
await unlink(join(dir, "PROMPT.md"));
const paths = await store.parseFileScopeFromPrompt(task.id);
@@ -1928,7 +1928,7 @@ describe("TaskStore", () => {
it("handles glob patterns in backtick-quoted paths", async () => {
const task = await store.createTask({ description: "Glob scope" });
const dir = join(rootDir, ".kb", "tasks", task.id);
const dir = join(rootDir, ".fusion", "tasks", task.id);
await writeFile(
join(dir, "PROMPT.md"),
`# ${task.id}: Glob scope
@@ -2512,7 +2512,7 @@ describe("TaskStore", () => {
const refined = await store.refineTask(task.id, "Need improvements");
// Verify file exists in new task directory
const attachDir = join(rootDir, ".kb", "tasks", refined.id, "attachments");
const attachDir = join(rootDir, ".fusion", "tasks", refined.id, "attachments");
const files = await readdir(attachDir);
expect(files.length).toBe(1);
@@ -3006,7 +3006,7 @@ describe("TaskStore", () => {
await store.moveTask(task.id, "done");
await store.archiveTask(task.id);
const dir = join(rootDir, ".kb", "tasks", task.id);
const dir = join(rootDir, ".fusion", "tasks", task.id);
expect(existsSync(dir)).toBe(true);
await store.cleanupArchivedTasks();
@@ -3144,7 +3144,7 @@ describe("TaskStore", () => {
await store.archiveTask(task.id);
await store.cleanupArchivedTasks();
const dir = join(rootDir, ".kb", "tasks", task.id);
const dir = join(rootDir, ".fusion", "tasks", task.id);
expect(existsSync(dir)).toBe(false);
// Unarchive should restore from archive
@@ -3201,7 +3201,7 @@ describe("TaskStore", () => {
await store.archiveTask(task.id);
// Delete directory without archiving
const dir = join(rootDir, ".kb", "tasks", task.id);
const dir = join(rootDir, ".fusion", "tasks", task.id);
const { rm } = await import("node:fs/promises");
await rm(dir, { recursive: true, force: true });
@@ -3252,7 +3252,7 @@ describe("TaskStore", () => {
await store.archiveTask(task.id);
await store.cleanupArchivedTasks();
const dir = join(rootDir, ".kb", "tasks", task.id);
const dir = join(rootDir, ".fusion", "tasks", task.id);
expect(existsSync(dir)).toBe(false);
await store.unarchiveTask(task.id);
@@ -3275,7 +3275,7 @@ describe("TaskStore", () => {
expect(archived.column).toBe("archived");
// Directory should be gone immediately
const dir = join(rootDir, ".kb", "tasks", task.id);
const dir = join(rootDir, ".fusion", "tasks", task.id);
expect(existsSync(dir)).toBe(false);
// Should be in archive.jsonl
@@ -3294,7 +3294,7 @@ describe("TaskStore", () => {
const archived = await store.archiveTaskAndCleanup(task.id);
expect(archived.column).toBe("archived");
const dir = join(rootDir, ".kb", "tasks", task.id);
const dir = join(rootDir, ".fusion", "tasks", task.id);
expect(existsSync(dir)).toBe(false);
});
@@ -3309,7 +3309,7 @@ describe("TaskStore", () => {
expect(archived.column).toBe("archived");
// Directory should still exist
const dir = join(rootDir, ".kb", "tasks", task.id);
const dir = join(rootDir, ".fusion", "tasks", task.id);
expect(existsSync(dir)).toBe(true);
});
@@ -3324,7 +3324,7 @@ describe("TaskStore", () => {
expect(archived.column).toBe("archived");
// Directory should still exist (default is false)
const dir = join(rootDir, ".kb", "tasks", task.id);
const dir = join(rootDir, ".fusion", "tasks", task.id);
expect(existsSync(dir)).toBe(true);
});
});

View File

@@ -61,7 +61,7 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
constructor(private rootDir: string, globalSettingsDir?: string) {
super();
this.setMaxListeners(100);
this.kbDir = join(rootDir, ".kb");
this.kbDir = join(rootDir, ".fusion");
this.tasksDir = join(this.kbDir, "tasks");
this.configPath = join(this.kbDir, "config.json");
this.archiveLogPath = join(this.kbDir, "archive.jsonl");