feat: rename data directory, add global project settings, multi-project CLI commands, and provider badge in model selector

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
gsxdsm
2026-04-02 09:10:42 -07:00
parent 1fa8837c6b
commit 566f531361
80 changed files with 857 additions and 652 deletions

View File

@@ -32,6 +32,9 @@ function asLocalProjectContext(store: TaskStore): ProjectContext {
async function getCommandContext(projectName?: string): Promise<CommandContext> {
if (projectName) {
const context = await resolveProject(projectName);
if (!context) {
throw new Error(`Project ${projectName} not found`);
}
return {
store: context.store,
projectPath: context.projectPath,
@@ -42,6 +45,9 @@ async function getCommandContext(projectName?: string): Promise<CommandContext>
try {
const context = await resolveProject(undefined);
if (!context) {
throw new Error("No project context");
}
return {
store: context.store,
projectPath: context.projectPath,
@@ -112,7 +118,7 @@ export async function runTaskCreate(descriptionArg?: string, attachFiles?: strin
if (task.dependencies.length > 0) {
console.log(` Dependencies: ${task.dependencies.join(", ")}`);
}
console.log(` Path: .kb/tasks/${task.id}/`);
console.log(` Path: .fusion/tasks/${task.id}/`);
if (attachFiles && attachFiles.length > 0) {
const { readFile } = await import("node:fs/promises");
@@ -321,7 +327,7 @@ export async function runTaskLogs(id: string, options: LogsOptions = {}, project
if (options.follow) {
const followStore = store;
const projectPath = projectContext?.projectPath ?? process.cwd();
const logPath = join(projectPath, ".kb", "tasks", id, "agent.log");
const logPath = join(projectPath, ".fusion", "tasks", id, "agent.log");
if (!existsSync(logPath)) {
console.log(`\n Waiting for log file to be created...`);
@@ -514,7 +520,7 @@ export async function runTaskAttach(id: string, filePath: string, projectName?:
console.log();
console.log(` ✓ Attached to ${id}: ${attachment.originalName}`);
console.log(` File: ${attachment.filename} (${sizeKB} KB)`);
console.log(` Path: .kb/tasks/${id}/attachments/${attachment.filename}`);
console.log(` Path: .fusion/tasks/${id}/attachments/${attachment.filename}`);
console.log();
}
@@ -557,7 +563,7 @@ export async function runTaskDuplicate(id: string, projectName?: string) {
console.log();
console.log(` ✓ Duplicated ${id}${newTask.id}`);
console.log(` Path: .kb/tasks/${newTask.id}/`);
console.log(` Path: .fusion/tasks/${newTask.id}/`);
console.log();
}
@@ -589,7 +595,7 @@ export async function runTaskRefine(id: string, feedbackArg?: string, projectNam
console.log(` ✓ Created refinement ${newTask.id} for ${id}`);
console.log(` Column: triage`);
console.log(` Dependency: ${id}`);
console.log(` Path: .kb/tasks/${newTask.id}/`);
console.log(` Path: .fusion/tasks/${newTask.id}/`);
console.log();
}
@@ -651,6 +657,7 @@ export async function runTaskDelete(id: string, force?: boolean, projectName?: s
} catch (err: any) {
console.error(`✗ Task ${id} not found`);
process.exit(1);
return;
}
// Prompt for confirmation unless force is used
@@ -663,6 +670,7 @@ export async function runTaskDelete(id: string, force?: boolean, projectName?: s
if (trimmed !== "y" && trimmed !== "yes") {
console.log("Cancelled.");
process.exit(0);
return;
}
}
@@ -674,6 +682,7 @@ export async function runTaskDelete(id: string, force?: boolean, projectName?: s
} catch (err: any) {
console.error(`✗ Failed to delete ${id}: ${err.message}`);
process.exit(1);
return;
}
}
@@ -1547,7 +1556,7 @@ export async function runTaskPlan(initialPlanArg?: string, yesFlag = false, proj
if (task.dependencies.length > 0) {
console.log(` Dependencies: ${task.dependencies.join(", ")}`);
}
console.log(` Path: .kb/tasks/${task.id}/`);
console.log(` Path: .fusion/tasks/${task.id}/`);
console.log();
} else {
console.log("\n Task creation cancelled.\n");