feat: migrate src/ core TS files to LogTape structured logging

Migrate 5 non-test TS files in src/ from console.* to LogTape:
- src/env.ts → getLogger('sf.core.env')
- src/resource-loader.ts → getLogger('sf.core.resource-loader')
- src/web/undo-service.ts → getLogger('sf.web.undo-service')
- src/web/cleanup-service.ts → getLogger('sf.web.cleanup-service')
- src/web/auto-dashboard-service.ts → getLogger('sf.web.auto-dashboard-service')

console.error(err) → log.error(msg, {error: err})
console.warn(msg) → log.warn(msg)

All CLI-facing output preserved. typecheck, lint pass.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
This commit is contained in:
Mikael Hugo 2026-05-08 21:01:08 +02:00
parent a46cbcbe40
commit 6e6363da0d
5 changed files with 30 additions and 17 deletions

View file

@ -1,6 +1,9 @@
import { homedir } from "node:os";
import { join } from "node:path";
import { z } from "zod";
import { getLogger } from "./logger.js";
const log = getLogger("sf.core.env");
const optionalNonEmptyString = z.string().trim().min(1).optional();
@ -188,8 +191,8 @@ export function parseCompleteSfEnv(
.join("\n");
if (process.env.SF_DEBUG) {
console.warn(
`⚠️ Environment validation issues (first 5):\n${message}\n` +
log.warn(
`Environment validation issues (first 5):\n${message}\n` +
`Set SF_QUIET=1 to suppress this check.\n`,
);
}

View file

@ -34,6 +34,7 @@ import {
loadRegistry,
readManifestFromEntryPath,
} from "./extension-registry.js";
import { getLogger } from "./logger.js";
import { compareSemver } from "./update-check.js";
// Resolve resources directory — prefer dist/resources/ (stable, set at build time)
@ -55,6 +56,8 @@ const resourcesDir =
? distResources
: srcResources;
const bundledExtensionsDir = join(resourcesDir, "extensions");
const log = getLogger("sf.core.resource-loader");
const resourceVersionManifestName = "managed-resources.json";
interface ManagedResourceManifest {
@ -549,9 +552,7 @@ function reconcileSymlink(link: string, target: string): void {
try {
symlinkSync(target, link, "junction");
} catch (err) {
console.error(
`[forge] WARN: Failed to symlink ${link}${target}: ${err instanceof Error ? err.message : err}`,
);
log.warn(`Failed to symlink ${link}${target}`, { error: err });
}
}
@ -613,9 +614,9 @@ function reconcileMergedNodeModules(
}
}
} catch (err) {
console.error(
`[forge] WARN: Failed to read hoisted node_modules at ${hoisted}: ${err instanceof Error ? err.message : err}`,
);
log.warn(`Failed to read hoisted node_modules at ${hoisted}`, {
error: err,
});
}
// Overlay internal node_modules entries that weren't hoisted.
@ -640,9 +641,9 @@ function reconcileMergedNodeModules(
}
}
} catch (err) {
console.error(
`[forge] WARN: Failed to read internal node_modules at ${internal}: ${err instanceof Error ? err.message : err}`,
);
log.warn(`Failed to read internal node_modules at ${internal}`, {
error: err,
});
}
// Only stamp marker if we actually linked something — avoids caching a broken state

View file

@ -3,12 +3,15 @@ import { existsSync, readFileSync } from "node:fs";
import { join } from "node:path";
import { pathToFileURL } from "node:url";
import { getLogger } from "../logger.js";
import type { AutoDashboardData } from "./bridge-service.ts";
import {
buildSubprocessPrefixArgs,
resolveSubprocessModule,
} from "./ts-subprocess-flags.ts";
const log = getLogger("sf.web.auto-dashboard-service");
const AUTO_DASHBOARD_MAX_BUFFER = 1024 * 1024;
const TEST_AUTO_DASHBOARD_MODULE_ENV = "SF_WEB_TEST_AUTO_DASHBOARD_MODULE";
const TEST_AUTO_DASHBOARD_FALLBACK_ENV =
@ -92,7 +95,7 @@ function reconcileWithDiskState(
try {
JSON.parse(readFileSync(pausedPath, "utf-8"));
} catch (err) {
console.warn(
log.warn(
`[auto-dashboard] paused-session.json corrupt: ${err instanceof Error ? err.message : String(err)} — still reporting paused`,
);
}

View file

@ -6,12 +6,15 @@ import type {
CleanupData,
CleanupResult,
} from "../../web/lib/remaining-command-types.ts";
import { getLogger } from "../logger.js";
import { resolveBridgeRuntimeConfig } from "./bridge-service.ts";
import {
buildSubprocessPrefixArgs,
resolveSubprocessModule,
} from "./ts-subprocess-flags.ts";
const _log = getLogger("sf.web.cleanup-service");
const CLEANUP_MAX_BUFFER = 2 * 1024 * 1024;
const CLEANUP_MODULE_ENV = "SF_CLEANUP_MODULE";
@ -65,17 +68,17 @@ export async function collectCleanupData(
"const basePath = process.env.SF_CLEANUP_BASE;",
// Get all SF branches
"let branches = [];",
'try { branches = mod.nativeBranchList(basePath, "sf/*"); } catch (e) { console.warn("[cleanup-service] nativeBranchList failed:", e && e.message ? e.message : e); }',
'try { branches = mod.nativeBranchList(basePath, "sf/*"); } catch (e) { _log.warn("[cleanup-service] nativeBranchList failed:", { error: e }); }',
// Detect main branch and find which SF branches are merged
'let mainBranch = "main";',
'try { mainBranch = mod.nativeDetectMainBranch(basePath); } catch (e) { console.warn("[cleanup-service] nativeDetectMainBranch failed — falling back to \\"main\\":", e && e.message ? e.message : e); }',
'try { mainBranch = mod.nativeDetectMainBranch(basePath); } catch (e) { _log.warn("[cleanup-service] nativeDetectMainBranch failed — falling back to \\"main\\":", { error: e }); }',
"let merged = [];",
'try { merged = mod.nativeBranchListMerged(basePath, mainBranch, "sf/*"); } catch (e) { console.warn("[cleanup-service] nativeBranchListMerged failed:", e && e.message ? e.message : e); }',
'try { merged = mod.nativeBranchListMerged(basePath, mainBranch, "sf/*"); } catch (e) { _log.warn("[cleanup-service] nativeBranchListMerged failed:", { error: e }); }',
"const mergedSet = new Set(merged);",
"const branchList = branches.map(b => ({ name: b, merged: mergedSet.has(b) }));",
// Get snapshot refs
"let refs = [];",
'try { refs = mod.nativeForEachRef(basePath, "refs/sf/snapshots/"); } catch (e) { console.warn("[cleanup-service] nativeForEachRef failed:", e && e.message ? e.message : e); }',
'try { refs = mod.nativeForEachRef(basePath, "refs/sf/snapshots/"); } catch (e) { _log.warn("[cleanup-service] nativeForEachRef failed:", { error: e }); }',
"const snapshotList = refs.map(r => {",
' const parts = r.split(" ");',
' return { ref: parts[0] || r, date: parts.length > 1 ? parts.slice(1).join(" ") : "" };',

View file

@ -6,12 +6,15 @@ import type {
UndoInfo,
UndoResult,
} from "../../web/lib/remaining-command-types.ts";
import { getLogger } from "../logger.js";
import { resolveBridgeRuntimeConfig } from "./bridge-service.ts";
import {
buildSubprocessPrefixArgs,
resolveSubprocessModule,
} from "./ts-subprocess-flags.ts";
const _log = getLogger("sf.web.undo-service");
const UNDO_MAX_BUFFER = 2 * 1024 * 1024;
const UNDO_MODULE_ENV = "SF_UNDO_MODULE";
const PATHS_MODULE_ENV = "SF_PATHS_MODULE";
@ -207,7 +210,7 @@ export async function executeUndo(
' const { execFileSync } = await import("node:child_process");',
" for (const sha of commits.reverse()) {",
' try { execFileSync("git", ["revert", "--no-commit", sha], { cwd: basePath, stdio: "pipe" }); commitsReverted++; }',
' catch (e) { console.warn("[undo-service] git revert failed for " + sha + ":", e && e.message ? e.message : e); try { execFileSync("git", ["revert", "--abort"], { cwd: basePath, stdio: "pipe" }); } catch {} break; }',
' catch (e) { _log.warn("[undo-service] git revert failed for " + sha + ":", { error: e }); try { execFileSync("git", ["revert", "--abort"], { cwd: basePath, stdio: "pipe" }); } catch {} break; }',
" }",
" }",
"}",