refactor(sf-ext): replace inline sfHome patterns with canonical sfHome()
Fix bug in auto.js where SF_HOME env var caused double '.sf' path segment. Convert 11 files from inline homedir()/.sf or SF_HOME constructs to sfHome(). Files updated: - auto.js: bug fix (join(SF_HOME, '.sf', 'agent') → join(sfHome(), 'agent')) - key-manager.js: process.env.SF_HOME || join(HOME, '.sf') → sfHome() - ui/color-band.js: os.homedir()/.sf → sfHome(); remove os import - ui/prompt-history.js: homedir()/.sf → sfHome(); remove homedir import - ui/usage-bar.js: homedir()/.sf/agent/auth.json → sfHome() - ui/marketplace.js: 2 occurrences — extensions dir → sfHome() - skill-telemetry.js: 2 occurrences — legacy skills dir → sfHome() - preferences-skills.js: legacy skills dir → sfHome() - preferences-models.js: models.json path → sfHome() - memory-embeddings.js: auth.json path → sfHome(); remove homedir import - commands/handlers/core.js: dynamic import homedir → static sfHome() Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
parent
0ece0e5413
commit
756355abf1
11 changed files with 24 additions and 19 deletions
|
|
@ -26,9 +26,9 @@ import {
|
|||
unlinkSync,
|
||||
writeFileSync,
|
||||
} from "node:fs";
|
||||
import { homedir } from "node:os";
|
||||
import { isAbsolute, join } from "node:path";
|
||||
import { pathToFileURL } from "node:url";
|
||||
import { sfHome } from "./sf-home.js";
|
||||
import {
|
||||
clearCmuxSidebar,
|
||||
logCmuxEvent,
|
||||
|
|
@ -1782,7 +1782,7 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
|
|||
// Using SF_PKG_ROOT constructs a correct absolute path in both contexts (#3949).
|
||||
const agentDir =
|
||||
process.env.SF_CODING_AGENT_DIR ||
|
||||
join(process.env.SF_HOME || homedir(), ".sf", "agent");
|
||||
join(sfHome(), "agent");
|
||||
const pkgRoot = process.env.SF_PKG_ROOT;
|
||||
const resourceLoaderPath = pkgRoot
|
||||
? pathToFileURL(join(pkgRoot, "dist", "resource-loader.js")).href
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import { formattedShortcutPair } from "../../shortcut-defs.js";
|
|||
import { deriveState } from "../../state.js";
|
||||
import { writeUokDiagnostics } from "../../uok/diagnostic-synthesis.js";
|
||||
import { projectRoot } from "../context.js";
|
||||
import { sfHome } from "../../sf-home.js";
|
||||
export function showHelp(ctx, args = "") {
|
||||
const summaryLines = [
|
||||
"SF — Singularity Forge\n",
|
||||
|
|
@ -1468,8 +1469,7 @@ async function handleResumeCommand(args, ctx) {
|
|||
// Fallback: show recent SF headless session files
|
||||
const { readdirSync, existsSync } = await import("node:fs");
|
||||
const { join: pathJoin } = await import("node:path");
|
||||
const { homedir } = await import("node:os");
|
||||
const sfDir = pathJoin(homedir(), ".sf");
|
||||
const sfDir = sfHome();
|
||||
const sessDir = pathJoin(sfDir, "sessions");
|
||||
if (!existsSync(sessDir)) {
|
||||
ctx.ui.notify(
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import { dirname, join } from "node:path";
|
|||
import { AuthStorage } from "@singularity-forge/coding-agent";
|
||||
import { getErrorMessage } from "./error-utils.js";
|
||||
import { isEnvAuthAllowed } from "./provider-env-auth.js";
|
||||
import { sfHome } from "./sf-home.js";
|
||||
export const PROVIDER_REGISTRY = [
|
||||
// LLM Providers
|
||||
{
|
||||
|
|
@ -250,8 +251,7 @@ export function describeCredential(cred) {
|
|||
* Get the auth.json path.
|
||||
*/
|
||||
export function getAuthPath() {
|
||||
const sfHome = process.env.SF_HOME || join(process.env.HOME ?? "~", ".sf");
|
||||
return join(sfHome, "agent", "auth.json");
|
||||
return join(sfHome(), "agent", "auth.json");
|
||||
}
|
||||
/**
|
||||
* Create an AuthStorage instance for key management.
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
// pipeline stages soft-degrade and `getRelevantMemoriesRanked` falls back
|
||||
// to static (confidence × hit_count) ranking.
|
||||
import { existsSync, readFileSync } from "node:fs";
|
||||
import { homedir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import {
|
||||
_getAdapter,
|
||||
|
|
@ -22,11 +21,12 @@ import {
|
|||
upsertMemoryEmbedding,
|
||||
} from "./sf-db.js";
|
||||
import { logWarning } from "./workflow-logger.js";
|
||||
import { sfHome } from "./sf-home.js";
|
||||
|
||||
/** Read the llm-gateway entry from ~/.sf/agent/auth.json if present. */
|
||||
function readGatewayFromAuthJson() {
|
||||
try {
|
||||
const authPath = join(homedir(), ".sf", "agent", "auth.json");
|
||||
const authPath = join(sfHome(), "agent", "auth.json");
|
||||
if (!existsSync(authPath)) return null;
|
||||
const data = JSON.parse(readFileSync(authPath, "utf8"));
|
||||
const entry = data["llm-gateway"];
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import { homedir } from "node:os";
|
|||
import { join } from "node:path";
|
||||
import { getModels, getProviders } from "@singularity-forge/ai";
|
||||
import { selectByBenchmarks } from "./benchmark-selector.js";
|
||||
import { sfHome } from "./sf-home.js";
|
||||
|
||||
import { defaultRoutingConfig, MODEL_CAPABILITY_TIER } from "./model-router.js";
|
||||
import {
|
||||
|
|
@ -535,7 +536,7 @@ export function resolveDefaultSessionModel(sessionProvider) {
|
|||
export function isCustomProvider(provider) {
|
||||
if (!provider) return false;
|
||||
const candidates = [
|
||||
join(homedir(), ".sf", "agent", "models.json"),
|
||||
join(sfHome(), "agent", "models.json"),
|
||||
join(homedir(), ".pi", "agent", "models.json"),
|
||||
];
|
||||
for (const path of candidates) {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import { existsSync, readdirSync, statSync } from "node:fs";
|
|||
import { homedir } from "node:os";
|
||||
import { isAbsolute, join } from "node:path";
|
||||
import { validatePreferences } from "./preferences-validation.js";
|
||||
import { sfHome } from "./sf-home.js";
|
||||
/**
|
||||
* Get skill search directories in priority order for resolution.
|
||||
*
|
||||
|
|
@ -25,7 +26,7 @@ export function getSkillSearchDirs(cwd) {
|
|||
{ dir: join(cwd, ".claude", "skills"), method: "project-skill" },
|
||||
];
|
||||
// Legacy fallback — read skills from old SF directory only if migration hasn't completed
|
||||
const legacyDir = join(homedir(), ".sf", "agent", "skills");
|
||||
const legacyDir = join(sfHome(), "agent", "skills");
|
||||
if (
|
||||
existsSync(legacyDir) &&
|
||||
!existsSync(join(legacyDir, ".migrated-to-agents"))
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
import { existsSync, readdirSync } from "node:fs";
|
||||
import { homedir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { sfHome } from "./sf-home.js";
|
||||
|
||||
// ─── In-memory state ──────────────────────────────────────────────────────────
|
||||
/** Skills available in the system prompt for the current unit */
|
||||
|
|
@ -28,7 +29,7 @@ const activelyLoadedSkills = new Set();
|
|||
export function captureAvailableSkills() {
|
||||
const skillsDir = join(homedir(), ".agents", "skills");
|
||||
const claudeSkillsDir = join(homedir(), ".claude", "skills");
|
||||
const legacyDir = join(homedir(), ".sf", "agent", "skills");
|
||||
const legacyDir = join(sfHome(), "agent", "skills");
|
||||
const names = listSkillNames(skillsDir);
|
||||
const claudeNames = listSkillNames(claudeSkillsDir);
|
||||
// Include skills still in the legacy directory only if migration hasn't completed
|
||||
|
|
@ -102,7 +103,7 @@ export function detectStaleSkills(units, thresholdDays) {
|
|||
// Check all installed skills, not just those with usage data
|
||||
const skillsDir = join(homedir(), ".agents", "skills");
|
||||
const claudeSkillsDir = join(homedir(), ".claude", "skills");
|
||||
const legacyDir = join(homedir(), ".sf", "agent", "skills");
|
||||
const legacyDir = join(sfHome(), "agent", "skills");
|
||||
const legacyMigrated = existsSync(join(legacyDir, ".migrated-to-agents"));
|
||||
const legacyNames = legacyMigrated ? [] : listSkillNames(legacyDir);
|
||||
const installedSet = new Set([
|
||||
|
|
|
|||
|
|
@ -4,15 +4,15 @@
|
|||
* Displays a colored band in the footer to visually distinguish sessions.
|
||||
*/
|
||||
import * as fs from "node:fs";
|
||||
import * as os from "node:os";
|
||||
import * as path from "node:path";
|
||||
import { sfHome } from "../sf-home.js";
|
||||
|
||||
const DEFAULT_CONFIG = {
|
||||
enabledByDefault: true,
|
||||
blockChar: "▁",
|
||||
blockCount: "full",
|
||||
};
|
||||
const STATE_FILE = path.join(os.homedir(), ".sf", "session-color-state.json");
|
||||
const STATE_FILE = path.join(sfHome(), "session-color-state.json");
|
||||
const COLOR_PALETTE = [
|
||||
196, 51, 226, 129, 46, 208, 27, 213, 118, 160, 87, 220, 93, 34, 202, 75, 199,
|
||||
154, 124, 45, 214, 135, 40, 166, 69, 205, 190, 88, 80, 228, 97, 28, 172, 63,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
||||
import { homedir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { sfHome } from "../sf-home.js";
|
||||
import {
|
||||
Key,
|
||||
matchesKey,
|
||||
|
|
@ -92,7 +93,7 @@ function scanInstalledExtensions(dir, sourceLabel) {
|
|||
}
|
||||
function buildCatalog() {
|
||||
const installed = scanInstalledExtensions(
|
||||
join(homedir(), ".sf", "agent", "extensions"),
|
||||
join(sfHome(), "agent", "extensions"),
|
||||
"installed",
|
||||
);
|
||||
const piCompat = scanInstalledExtensions(
|
||||
|
|
@ -317,7 +318,7 @@ export function installExtensionNpm(packageId, displayName) {
|
|||
return;
|
||||
}
|
||||
import("node:child_process").then(({ spawn }) => {
|
||||
const target = join(homedir(), ".sf", "agent", "extensions");
|
||||
const target = join(sfHome(), "agent", "extensions");
|
||||
const proc = spawn("npm", ["install", "--prefix", target, packageId], {
|
||||
stdio: ["ignore", "pipe", "pipe"],
|
||||
detached: false,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { appendFileSync, existsSync, mkdirSync, readFileSync } from "node:fs";
|
||||
import { homedir } from "node:os";
|
||||
import { dirname, join } from "node:path";
|
||||
import {
|
||||
Key,
|
||||
|
|
@ -7,11 +6,12 @@ import {
|
|||
truncateToWidth,
|
||||
visibleWidth,
|
||||
} from "@singularity-forge/tui";
|
||||
import { sfHome } from "../sf-home.js";
|
||||
|
||||
const LIMIT = 20;
|
||||
const SCAN_LINE_LIMIT = 2000;
|
||||
function promptHistoryPath() {
|
||||
return join(homedir(), ".sf", "agent", "prompt-history.jsonl");
|
||||
return join(sfHome(), "agent", "prompt-history.jsonl");
|
||||
}
|
||||
function isEnvTruthy(value) {
|
||||
return ["1", "true", "TRUE", "yes", "YES"].includes(String(value ?? ""));
|
||||
|
|
|
|||
|
|
@ -19,12 +19,13 @@ import {
|
|||
setupUser,
|
||||
} from "@google/gemini-cli-core";
|
||||
import { visibleWidth } from "@singularity-forge/tui";
|
||||
import { sfHome } from "../sf-home.js";
|
||||
|
||||
// ============================================================================
|
||||
// Auth helper
|
||||
// ============================================================================
|
||||
function loadAuthJson() {
|
||||
const sfAuthPath = path.join(os.homedir(), ".sf", "agent", "auth.json");
|
||||
const sfAuthPath = path.join(sfHome(), "agent", "auth.json");
|
||||
try {
|
||||
if (fs.existsSync(sfAuthPath)) {
|
||||
return JSON.parse(fs.readFileSync(sfAuthPath, "utf-8"));
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue