refactor: eliminate ~400 no-explicit-any warnings across the workspace
Parallel subagent pass: four typescript-pro agents on non-overlapping scopes.
Patterns applied:
- catch (err: any) { ... err.message ... } → catch (err) { ... getErrorMessage(err) ... }
using the new @fusion/core helper. Bare catch {} where the error was unused.
- SQLite row types: defined typed XxxRow interfaces per table and cast
.all()/.get() results via `as unknown as XxxRow[]` (the double cast is
required because better-sqlite3 returns Record<string, SQLOutputValue>).
- rowToX(row: any) converters: typed argument with the matching row interface.
- Dynamic settings key writes: (settings as Record<string, unknown>)[key].
- React event handlers and setState callbacks: inferred types or concrete
React.{Mouse,Change,Form}Event<...> where needed.
- pi-claude-cli: local PiMessage / PiContext duck types to avoid re-typing
pi-ai concrete shapes; typed Claude stream event message fields.
72 files changed, ~400 anys eliminated. Typecheck passes across the workspace.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -153,20 +153,20 @@ const upload = multer({
|
||||
|
||||
const execFileAsync = promisify(execFile);
|
||||
|
||||
function readJsonObject(path: string): Record<string, any> {
|
||||
function readJsonObject(path: string): Record<string, unknown> {
|
||||
if (!nodeFs.existsSync(path)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
try {
|
||||
const parsed = JSON.parse(nodeFs.readFileSync(path, "utf-8"));
|
||||
return parsed && typeof parsed === "object" ? parsed as Record<string, any> : {};
|
||||
return parsed && typeof parsed === "object" ? parsed as Record<string, unknown> : {};
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
function hasPackageManagerSettings(settings: Record<string, any>): boolean {
|
||||
function hasPackageManagerSettings(settings: Record<string, unknown>): boolean {
|
||||
return Array.isArray(settings.packages) || Array.isArray(settings.npmCommand);
|
||||
}
|
||||
|
||||
@@ -215,6 +215,7 @@ async function discoverDashboardPiExtensions(cwd: string): Promise<PiExtensionSe
|
||||
getNpmCommand: () => Array.isArray(mergedSettings.npmCommand)
|
||||
? [...mergedSettings.npmCommand]
|
||||
: undefined,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- settingsManager shape varies across pi-coding-agent versions; typed as any per upstream API
|
||||
} as any,
|
||||
});
|
||||
const resolved = await packageManager.resolve(async () => "skip");
|
||||
@@ -15153,7 +15154,7 @@ async function persistImportedSkills(
|
||||
await central.init();
|
||||
|
||||
const localNodes = await central.listNodes();
|
||||
const localNode = localNodes.find((n: any) => n.type === "local");
|
||||
const localNode = localNodes.find((n: { type?: string; id?: string }) => n.type === "local");
|
||||
|
||||
if (localNode && localNode.id === nodeId) {
|
||||
// Local node — fall through to existing filesystem logic below
|
||||
@@ -15198,11 +15199,12 @@ async function persistImportedSkills(
|
||||
}
|
||||
res.status(proxyRes.status);
|
||||
res.send(body);
|
||||
} catch (fetchErr: any) {
|
||||
if (fetchErr.name === "AbortError" || fetchErr.code === "ETIMEDOUT") {
|
||||
throw new ApiError(504, `Remote node timeout: ${fetchErr.message}`);
|
||||
} catch (fetchErr) {
|
||||
const e = fetchErr as { name?: string; code?: string; message?: string };
|
||||
if (e.name === "AbortError" || e.code === "ETIMEDOUT") {
|
||||
throw new ApiError(504, `Remote node timeout: ${e.message ?? String(fetchErr)}`);
|
||||
}
|
||||
throw new ApiError(502, `Remote node error: ${fetchErr.message}`);
|
||||
throw new ApiError(502, `Remote node error: ${e.message ?? String(fetchErr)}`);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -219,85 +219,84 @@ export function createSSE(
|
||||
};
|
||||
|
||||
// --- Event handler definitions ---
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any -- EventEmitter handlers receive untyped event data */
|
||||
const onCreated = (task: any) => {
|
||||
const onCreated = (task: unknown) => {
|
||||
send(`event: task:created\ndata: ${JSON.stringify(stripTaskListHeavyFields(task))}\n\n`);
|
||||
};
|
||||
const onMoved = (data: any) => {
|
||||
const onMoved = (data: unknown) => {
|
||||
send(`event: task:moved\ndata: ${JSON.stringify(stripTaskEventHeavyFields(data))}\n\n`);
|
||||
};
|
||||
const onUpdated = (task: any) => {
|
||||
const onUpdated = (task: unknown) => {
|
||||
send(`event: task:updated\ndata: ${JSON.stringify(stripTaskListHeavyFields(task))}\n\n`);
|
||||
};
|
||||
const onDeleted = (task: any) => {
|
||||
const onDeleted = (task: unknown) => {
|
||||
send(`event: task:deleted\ndata: ${JSON.stringify(stripTaskListHeavyFields(task))}\n\n`);
|
||||
};
|
||||
const onMerged = (result: any) => {
|
||||
const onMerged = (result: unknown) => {
|
||||
send(`event: task:merged\ndata: ${JSON.stringify(stripTaskEventHeavyFields(result))}\n\n`);
|
||||
};
|
||||
|
||||
const onMissionCreated = (data: any) => {
|
||||
const onMissionCreated = (data: unknown) => {
|
||||
send(`event: mission:created\ndata: ${JSON.stringify(data)}\n\n`);
|
||||
};
|
||||
const onMissionUpdated = (data: any) => {
|
||||
const onMissionUpdated = (data: unknown) => {
|
||||
send(`event: mission:updated\ndata: ${JSON.stringify(data)}\n\n`);
|
||||
};
|
||||
const onMissionDeleted = (data: any) => {
|
||||
const onMissionDeleted = (data: unknown) => {
|
||||
send(`event: mission:deleted\ndata: ${JSON.stringify(data)}\n\n`);
|
||||
};
|
||||
const onMilestoneCreated = (data: any) => {
|
||||
const onMilestoneCreated = (data: unknown) => {
|
||||
send(`event: milestone:created\ndata: ${JSON.stringify(data)}\n\n`);
|
||||
};
|
||||
const onMilestoneUpdated = (data: any) => {
|
||||
const onMilestoneUpdated = (data: unknown) => {
|
||||
send(`event: milestone:updated\ndata: ${JSON.stringify(data)}\n\n`);
|
||||
};
|
||||
const onMilestoneDeleted = (data: any) => {
|
||||
const onMilestoneDeleted = (data: unknown) => {
|
||||
send(`event: milestone:deleted\ndata: ${JSON.stringify(data)}\n\n`);
|
||||
};
|
||||
const onSliceCreated = (data: any) => {
|
||||
const onSliceCreated = (data: unknown) => {
|
||||
send(`event: slice:created\ndata: ${JSON.stringify(data)}\n\n`);
|
||||
};
|
||||
const onSliceUpdated = (data: any) => {
|
||||
const onSliceUpdated = (data: unknown) => {
|
||||
send(`event: slice:updated\ndata: ${JSON.stringify(data)}\n\n`);
|
||||
};
|
||||
const onSliceDeleted = (data: any) => {
|
||||
const onSliceDeleted = (data: unknown) => {
|
||||
send(`event: slice:deleted\ndata: ${JSON.stringify(data)}\n\n`);
|
||||
};
|
||||
const onSliceActivated = (data: any) => {
|
||||
const onSliceActivated = (data: unknown) => {
|
||||
send(`event: slice:activated\ndata: ${JSON.stringify(data)}\n\n`);
|
||||
};
|
||||
const onFeatureCreated = (data: any) => {
|
||||
const onFeatureCreated = (data: unknown) => {
|
||||
send(`event: feature:created\ndata: ${JSON.stringify(data)}\n\n`);
|
||||
};
|
||||
const onFeatureUpdated = (data: any) => {
|
||||
const onFeatureUpdated = (data: unknown) => {
|
||||
send(`event: feature:updated\ndata: ${JSON.stringify(data)}\n\n`);
|
||||
};
|
||||
const onFeatureDeleted = (data: any) => {
|
||||
const onFeatureDeleted = (data: unknown) => {
|
||||
send(`event: feature:deleted\ndata: ${JSON.stringify(data)}\n\n`);
|
||||
};
|
||||
const onFeatureLinked = (data: any) => {
|
||||
const onFeatureLinked = (data: unknown) => {
|
||||
send(`event: feature:linked\ndata: ${JSON.stringify(data)}\n\n`);
|
||||
};
|
||||
const onAssertionCreated = (data: any) => {
|
||||
const onAssertionCreated = (data: unknown) => {
|
||||
send(`event: assertion:created\ndata: ${JSON.stringify(data)}\n\n`);
|
||||
};
|
||||
const onAssertionUpdated = (data: any) => {
|
||||
const onAssertionUpdated = (data: unknown) => {
|
||||
send(`event: assertion:updated\ndata: ${JSON.stringify(data)}\n\n`);
|
||||
};
|
||||
const onAssertionDeleted = (data: any) => {
|
||||
const onAssertionDeleted = (data: unknown) => {
|
||||
send(`event: assertion:deleted\ndata: ${JSON.stringify(data)}\n\n`);
|
||||
};
|
||||
const onAssertionLinked = (data: any) => {
|
||||
const onAssertionLinked = (data: unknown) => {
|
||||
send(`event: assertion:linked\ndata: ${JSON.stringify(data)}\n\n`);
|
||||
};
|
||||
const onAssertionUnlinked = (data: any) => {
|
||||
const onAssertionUnlinked = (data: unknown) => {
|
||||
send(`event: assertion:unlinked\ndata: ${JSON.stringify(data)}\n\n`);
|
||||
};
|
||||
const onMissionEvent = (data: any) => {
|
||||
const onMissionEvent = (data: unknown) => {
|
||||
send(`event: mission:event\ndata: ${JSON.stringify(data)}\n\n`);
|
||||
};
|
||||
|
||||
const onMilestoneValidationUpdated = (data: any) => {
|
||||
const onMilestoneValidationUpdated = (data: unknown) => {
|
||||
send(`event: milestone:validation:updated\ndata: ${JSON.stringify(data)}\n\n`);
|
||||
};
|
||||
|
||||
@@ -313,15 +312,13 @@ export function createSSE(
|
||||
send(`event: fix-feature:created\ndata: ${JSON.stringify(payload)}\n\n`);
|
||||
};
|
||||
|
||||
const onAiSessionUpdated = (data: any) => {
|
||||
const onAiSessionUpdated = (data: unknown) => {
|
||||
send(`event: ai_session:updated\ndata: ${JSON.stringify(data)}\n\n`);
|
||||
};
|
||||
const onAiSessionDeleted = (data: any) => {
|
||||
const onAiSessionDeleted = (data: unknown) => {
|
||||
send(`event: ai_session:deleted\ndata: ${JSON.stringify(data)}\n\n`);
|
||||
};
|
||||
|
||||
/* eslint-enable @typescript-eslint/no-explicit-any */
|
||||
|
||||
// --- Unified plugin lifecycle handler ---
|
||||
// Instead of emitting individual plugin events, we normalize all plugin
|
||||
// lifecycle changes into a single `plugin:lifecycle` SSE event with
|
||||
@@ -358,11 +355,11 @@ export function createSSE(
|
||||
};
|
||||
|
||||
// --- Agent lifecycle event handlers ---
|
||||
const onAgentCreated = (agent: any) => {
|
||||
const onAgentCreated = (agent: unknown) => {
|
||||
send(`event: agent:created\ndata: ${JSON.stringify(agent)}\n\n`);
|
||||
};
|
||||
|
||||
const onAgentUpdated = (agent: any) => {
|
||||
const onAgentUpdated = (agent: unknown) => {
|
||||
send(`event: agent:updated\ndata: ${JSON.stringify(agent)}\n\n`);
|
||||
};
|
||||
|
||||
@@ -392,11 +389,11 @@ export function createSSE(
|
||||
};
|
||||
|
||||
// --- Chat store event handlers ---
|
||||
const onChatSessionCreated = (session: any) => {
|
||||
const onChatSessionCreated = (session: unknown) => {
|
||||
send(`event: chat:session:created\ndata: ${JSON.stringify(session)}\n\n`);
|
||||
};
|
||||
|
||||
const onChatSessionUpdated = (session: any) => {
|
||||
const onChatSessionUpdated = (session: unknown) => {
|
||||
send(`event: chat:session:updated\ndata: ${JSON.stringify(session)}\n\n`);
|
||||
};
|
||||
|
||||
@@ -404,7 +401,7 @@ export function createSSE(
|
||||
send(`event: chat:session:deleted\ndata: ${JSON.stringify({ id: sessionId })}\n\n`);
|
||||
};
|
||||
|
||||
const onChatMessageAdded = (message: any) => {
|
||||
const onChatMessageAdded = (message: unknown) => {
|
||||
send(`event: chat:message:added\ndata: ${JSON.stringify(message)}\n\n`);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user