refactor: low-regret cleanup across core, engine, dashboard
- core: extract ai-engine-loader.ts to share @fusion/engine dynamic-import boilerplate between ai-summarize and memory-compaction (incl. AgentMessage type); collapse getInbox/getOutbox, listInsights/countInsights, listRuns/countRuns, and three hasProjectDb* variants behind shared helpers. - core: drop unused pluginLoaderLog export; tighten two `any` casts (db.walCheckpoint row, plugin-loader error.code). - engine: extract resolveRoleFallback helper from buildSessionSkillContext/Sync; remove 22 stale `eslint-disable no-explicit-any` directives across project-engine, self-healing, triage, worktree-pool. - dashboard: apply ESLint autofix (let→const, empty `interface extends`→type). All three packages: typecheck clean, full test suites pass (14,414 tests), builds clean. Net lint: -31 warnings. No public behavior changes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -466,7 +466,7 @@ export class ProjectEngine {
|
||||
}
|
||||
|
||||
// Intentional cast to access Task properties needed by merge validation
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
||||
if (!this.canMergeTask(task as any)) {
|
||||
continue;
|
||||
}
|
||||
@@ -488,7 +488,7 @@ export class ProjectEngine {
|
||||
}
|
||||
|
||||
// Auto-heal verification buffer failures by resetting retry counter
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
||||
if (this.hasAutoHealableVerificationBufferFailure(task as any)) {
|
||||
await store.logEntry(
|
||||
taskId,
|
||||
@@ -497,7 +497,7 @@ export class ProjectEngine {
|
||||
await store.updateTask(taskId, { mergeRetries: 0, error: null, status: null });
|
||||
} else if (
|
||||
(task.mergeRetries ?? 0) >= ProjectEngine.MAX_AUTO_MERGE_RETRIES &&
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
||||
this.isRetryCooldownElapsed(task as any)
|
||||
) {
|
||||
await store.logEntry(
|
||||
@@ -565,13 +565,13 @@ export class ProjectEngine {
|
||||
} else {
|
||||
// Direct merge via AI agent, gated by semaphore
|
||||
runtimeLog.log(`${manualResolver ? "Manual" : "Auto"}-merge merging ${taskId}...`);
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
||||
const semaphore = (this.runtime as any).globalSemaphore;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
||||
const pool = (this.runtime as any).worktreePool;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
||||
const agentStore = (this.runtime as any).agentStore;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
||||
const usageLimitPauser = (this.runtime as any).usageLimitPauser;
|
||||
|
||||
const rawMerge = () =>
|
||||
@@ -772,7 +772,7 @@ export class ProjectEngine {
|
||||
runtimeLog.log(`Startup sweep: clearing stale '${t.status}' status on ${t.id}`);
|
||||
await store.updateTask(t.id, { status: null });
|
||||
// Update in-memory object so canMergeTask sees the cleared status
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
||||
(t as any).status = null;
|
||||
}
|
||||
}
|
||||
@@ -780,7 +780,7 @@ export class ProjectEngine {
|
||||
const settings = await store.getSettings();
|
||||
if (!settings.autoMerge) return;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
||||
const eligible = tasks.filter((t) => this.canMergeTask(t as any));
|
||||
if (eligible.length > 0) {
|
||||
runtimeLog.log(`Auto-merge startup sweep: enqueueing ${eligible.length} task(s)`);
|
||||
@@ -806,7 +806,7 @@ export class ProjectEngine {
|
||||
if (!settings.globalPause && !settings.enginePaused && settings.autoMerge) {
|
||||
const tasks = await store.listTasks({ column: "in-review" });
|
||||
for (const t of tasks) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
||||
if (this.canMergeTask(t as any)) {
|
||||
this.internalEnqueueMerge(t.id);
|
||||
}
|
||||
@@ -864,7 +864,7 @@ export class ProjectEngine {
|
||||
runtimeLog.log("Global unpause — resuming agentic activity");
|
||||
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
||||
const executor = (this.runtime as any).executor;
|
||||
executor?.resumeOrphaned?.().catch((err: Error) =>
|
||||
runtimeLog.error("Failed to resume orphaned tasks on unpause:", err),
|
||||
@@ -879,7 +879,7 @@ export class ProjectEngine {
|
||||
try {
|
||||
const tasks = await store.listTasks({ column: "in-review" });
|
||||
for (const t of tasks) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
||||
if (this.canMergeTask(t as any)) {
|
||||
this.internalEnqueueMerge(t.id);
|
||||
}
|
||||
@@ -907,7 +907,7 @@ export class ProjectEngine {
|
||||
runtimeLog.log("Engine unpaused — resuming agentic activity");
|
||||
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
||||
const executor = (this.runtime as any).executor;
|
||||
executor?.resumeOrphaned?.().catch((err: Error) =>
|
||||
runtimeLog.error("Failed to resume orphaned tasks on engine unpause:", err),
|
||||
@@ -922,7 +922,7 @@ export class ProjectEngine {
|
||||
try {
|
||||
const tasks = await store.listTasks({ column: "in-review" });
|
||||
for (const t of tasks) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
||||
if (this.canMergeTask(t as any)) {
|
||||
this.internalEnqueueMerge(t.id);
|
||||
}
|
||||
@@ -951,7 +951,7 @@ export class ProjectEngine {
|
||||
`Stuck task timeout changed to ${s.taskStuckTimeoutMs}ms — running immediate check`,
|
||||
);
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
||||
const detector = (this.runtime as any).stuckTaskDetector;
|
||||
await detector?.checkNow?.();
|
||||
} catch (err: unknown) {
|
||||
@@ -982,9 +982,9 @@ export class ProjectEngine {
|
||||
"memoryDreamsSchedule",
|
||||
] as const;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
||||
const changed = insightKeys.some((key) => (s as any)[key] !== (prev as any)[key]);
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
||||
const dreamsChanged = dreamKeys.some((key) => (s as any)[key] !== (prev as any)[key]);
|
||||
if ((!changed && !dreamsChanged) || !this.automationStore) return;
|
||||
|
||||
@@ -1022,7 +1022,7 @@ export class ProjectEngine {
|
||||
"memoryAutoSummarizeSchedule",
|
||||
] as const;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
||||
const changed = autoSummarizeKeys.some((key) => (s as any)[key] !== (prev as any)[key]);
|
||||
if (!changed || !this.automationStore) return;
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
* by cleaning oldest idle worktrees when count exceeds 2× maxWorktrees.
|
||||
*/
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { exec } from "node:child_process";
|
||||
import { promisify } from "node:util";
|
||||
import { existsSync, readdirSync, statSync } from "node:fs";
|
||||
|
||||
@@ -204,24 +204,27 @@ export async function buildSessionSkillContext(
|
||||
}
|
||||
}
|
||||
|
||||
// Rule 2: Use role fallback skills
|
||||
return resolveRoleFallback(sessionPurpose, projectRootDir);
|
||||
}
|
||||
|
||||
function resolveRoleFallback(
|
||||
sessionPurpose: SessionPurpose,
|
||||
projectRootDir: string,
|
||||
): SessionSkillContextResult {
|
||||
const roleFallbackSkills = getRoleFallbackSkills(sessionPurpose);
|
||||
|
||||
if (roleFallbackSkills && roleFallbackSkills.length > 0) {
|
||||
const skillSelectionContext: SkillSelectionContext = {
|
||||
projectRootDir,
|
||||
requestedSkillNames: roleFallbackSkills,
|
||||
sessionPurpose,
|
||||
};
|
||||
|
||||
return {
|
||||
skillSelectionContext,
|
||||
skillSelectionContext: {
|
||||
projectRootDir,
|
||||
requestedSkillNames: roleFallbackSkills,
|
||||
sessionPurpose,
|
||||
},
|
||||
resolvedSkillNames: roleFallbackSkills,
|
||||
skillSource: "role-fallback",
|
||||
};
|
||||
}
|
||||
|
||||
// Rule 3: No skills available
|
||||
return {
|
||||
skillSelectionContext: undefined,
|
||||
resolvedSkillNames: [],
|
||||
@@ -263,27 +266,5 @@ export function buildSessionSkillContextSync(
|
||||
}
|
||||
}
|
||||
|
||||
// Rule 2: Use role fallback skills
|
||||
const roleFallbackSkills = getRoleFallbackSkills(sessionPurpose);
|
||||
|
||||
if (roleFallbackSkills && roleFallbackSkills.length > 0) {
|
||||
const skillSelectionContext: SkillSelectionContext = {
|
||||
projectRootDir,
|
||||
requestedSkillNames: roleFallbackSkills,
|
||||
sessionPurpose,
|
||||
};
|
||||
|
||||
return {
|
||||
skillSelectionContext,
|
||||
resolvedSkillNames: roleFallbackSkills,
|
||||
skillSource: "role-fallback",
|
||||
};
|
||||
}
|
||||
|
||||
// Rule 3: No skills available
|
||||
return {
|
||||
skillSelectionContext: undefined,
|
||||
resolvedSkillNames: [],
|
||||
skillSource: "none",
|
||||
};
|
||||
return resolveRoleFallback(sessionPurpose, projectRootDir);
|
||||
}
|
||||
|
||||
@@ -1364,7 +1364,7 @@ export class TriageProcessor {
|
||||
// Re-read task detail to get latest user comments for the reviewer
|
||||
const currentDetail = await store.getTask(taskId);
|
||||
const currentUserComments = (currentDetail.comments || []).filter(
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
||||
(c: any) => c.author === "user",
|
||||
);
|
||||
|
||||
@@ -1510,7 +1510,7 @@ export class TriageProcessor {
|
||||
}
|
||||
|
||||
const parsedDeps = await this.store.parseDependenciesFromPrompt(task.id);
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
||||
const taskUpdates: Record<string, any> = { status: null, error: null };
|
||||
|
||||
if (parsedDeps.length > 0) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { exec } from "node:child_process";
|
||||
import { promisify } from "node:util";
|
||||
import { existsSync, readdirSync, rmSync } from "node:fs";
|
||||
|
||||
Reference in New Issue
Block a user