Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions src/commands/ai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,13 @@
*/

import { readFileSync, writeFileSync, mkdirSync } from "node:fs";
import { join, resolve, dirname } from "node:path";
import { fileURLToPath } from "node:url";
import { join } from "node:path";
import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
import { repoRoot } from "../lib/repo-root";


const REPO_ROOT = process.env.CUE_REPO_ROOT ?? process.env.SOUL_REPO_ROOT ?? resolve(dirname(fileURLToPath(import.meta.url)), "..", "..");
const PROFILES_DIR = join(REPO_ROOT, "profiles");
const REGISTRY_PATH = join(REPO_ROOT, "docs", "registry", "index.json");
const PROFILES_DIR = join(repoRoot(), "profiles");
const REGISTRY_PATH = join(repoRoot(), "docs", "registry", "index.json");

interface MatchedProfile {
name: string;
Expand Down
7 changes: 3 additions & 4 deletions src/commands/ask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@
*/

import { readFileSync, existsSync, readdirSync } from "node:fs";
import { resolve, dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import { join } from "node:path";
import { repoRoot } from "../lib/repo-root";

const REPO_ROOT = process.env.CUE_REPO_ROOT ?? process.env.SOUL_REPO_ROOT ?? resolve(dirname(fileURLToPath(import.meta.url)), "..", "..");
const SKILLS_ROOT = join(REPO_ROOT, "resources", "skills", "skills");
const SKILLS_ROOT = join(repoRoot(), "resources", "skills", "skills");

export async function run(args: string[]): Promise<number> {
const query = args.filter(a => !a.startsWith("-")).join(" ");
Expand Down
8 changes: 3 additions & 5 deletions src/commands/benchmark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,11 @@
import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
import { join } from "node:path";
import { homedir } from "node:os";
import { resolve, dirname } from "node:path";
import { fileURLToPath } from "node:url";
import { parse as parseYaml } from "yaml";

import { resolveActiveProfile } from "../lib/cwd-resolver";
import { repoRoot } from "../lib/repo-root";

const REPO_ROOT = process.env.CUE_REPO_ROOT ?? process.env.SOUL_REPO_ROOT ?? resolve(dirname(fileURLToPath(import.meta.url)), "..", "..");

interface BenchmarkResult {
profile: string;
Expand Down Expand Up @@ -154,7 +152,7 @@ function scanSessions(profileName: string): BenchmarkResult {

// Load profile to find unused skills
try {
const profilePath = join(REPO_ROOT, "profiles", profileName, "profile.yaml");
const profilePath = join(repoRoot(), "profiles", profileName, "profile.yaml");
if (existsSync(profilePath)) {
const prof = parseYaml(readFileSync(profilePath, "utf8"));
const declared = (prof.skills?.local ?? []).map((s: string | { id: string }) =>
Expand Down Expand Up @@ -226,7 +224,7 @@ Metrics:
}

if (all) {
const profilesDir = join(REPO_ROOT, "profiles");
const profilesDir = join(repoRoot(), "profiles");
const profiles = readdirSync(profilesDir)
.filter(d => !d.startsWith("_") && existsSync(join(profilesDir, d, "profile.yaml")));

Expand Down
7 changes: 3 additions & 4 deletions src/commands/builtin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@
*/

import { readFileSync, writeFileSync } from "node:fs";
import { resolve, dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import { join } from "node:path";
import { repoRoot } from "../lib/repo-root";

const REPO_ROOT = process.env.CUE_REPO_ROOT ?? process.env.SOUL_REPO_ROOT ?? resolve(dirname(fileURLToPath(import.meta.url)), "..", "..");
const PROFILES_DIR = process.env.CUE_PROFILES_DIR ?? join(REPO_ROOT, "profiles");
const PROFILES_DIR = process.env.CUE_PROFILES_DIR ?? join(repoRoot(), "profiles");
const CORE_YAML = join(PROFILES_DIR, "core", "profile.yaml");

function getCoreSkills(): string[] {
Expand Down
7 changes: 3 additions & 4 deletions src/commands/clean.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@
*/

import { existsSync, readdirSync, rmSync, statSync, readFileSync } from "node:fs";
import { join, resolve, dirname } from "node:path";
import { fileURLToPath } from "node:url";
import { join } from "node:path";
import { homedir } from "node:os";

import { listProfiles } from "../lib/profile-loader";
import { repoRoot } from "../lib/repo-root";

const REPO_ROOT = process.env.CUE_REPO_ROOT ?? process.env.SOUL_REPO_ROOT ?? resolve(dirname(fileURLToPath(import.meta.url)), "..", "..");
const RUNTIME_ROOT = join(process.env.XDG_CONFIG_HOME ?? join(homedir(), ".config"), "cue", "runtime");
const CACHE_ROOT = join(REPO_ROOT, "profiles", "_cache", "npx");
const CACHE_ROOT = join(repoRoot(), "profiles", "_cache", "npx");

export async function run(args: string[]): Promise<number> {
if (args.includes("-h") || args.includes("--help")) {
Expand Down
7 changes: 3 additions & 4 deletions src/commands/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,15 @@

import { spawnSync } from "node:child_process";
import { readFileSync } from "node:fs";
import { join, dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import { join } from "node:path";
import { homedir, platform } from "node:os";

import { resolveProfileForCwd } from "../lib/cwd-resolver";
import { requiredClisFor } from "../lib/cli-extractor";
import { listProfiles } from "../lib/profile-loader";
import { repoRoot } from "../lib/repo-root";

const REPO_ROOT = process.env.CUE_REPO_ROOT ?? process.env.SOUL_REPO_ROOT ?? resolve(dirname(fileURLToPath(import.meta.url)), "..", "..");
const RECIPES_PATH = join(REPO_ROOT, "resources", "cli-recipes.json");
const RECIPES_PATH = join(repoRoot(), "resources", "cli-recipes.json");

type Recipe = Partial<Record<"apt" | "brew" | "dnf" | "pacman" | "snap" | "winget" | "pip" | "pipx" | "npm" | "script" | "manual" | "needs", string>>;

Expand Down
7 changes: 3 additions & 4 deletions src/commands/cloud.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@
*/

import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
import { join, resolve, dirname } from "node:path";
import { fileURLToPath } from "node:url";
import { join } from "node:path";
import { homedir } from "node:os";
import { repoRoot } from "../lib/repo-root";

const REPO_ROOT = process.env.CUE_REPO_ROOT ?? process.env.SOUL_REPO_ROOT ?? resolve(dirname(fileURLToPath(import.meta.url)), "..", "..");
const PROFILES_DIR = process.env.CUE_PROFILES_DIR ?? join(REPO_ROOT, "profiles");
const PROFILES_DIR = process.env.CUE_PROFILES_DIR ?? join(repoRoot(), "profiles");
const CONFIG_DIR = join(process.env.XDG_CONFIG_HOME ?? join(homedir(), ".config"), "cue");
const CREDS_FILE = join(CONFIG_DIR, "credentials.json");
const API_BASE = process.env.CUE_API_URL ?? "https://api.getcue.dev";
Expand Down
7 changes: 3 additions & 4 deletions src/commands/cost.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,18 @@
*/

import { readFileSync, existsSync, readdirSync } from "node:fs";
import { resolve, dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import { join } from "node:path";

import { loadProfile, listProfiles } from "../lib/profile-loader";
import { resolveActiveProfile } from "../lib/cwd-resolver";
import { repoRoot } from "../lib/repo-root";
import {
skillAlwaysOnTokens,
skillBodyTokens,
materializedClaudeMdTokens,
SKILLS_ROOT,
} from "../lib/profile-metrics";

const REPO_ROOT = process.env.CUE_REPO_ROOT ?? process.env.SOUL_REPO_ROOT ?? resolve(dirname(fileURLToPath(import.meta.url)), "..", "..");

// Expand wildcard (*/*) to all actual skill IDs on disk.
function expandSkillIds(ids: string[]): string[] {
Expand All @@ -39,7 +38,7 @@ function expandSkillIds(ids: string[]): string[] {
}
return result;
}
const MCP_CONFIGS_DIR = join(REPO_ROOT, "resources", "mcps", "configs");
const MCP_CONFIGS_DIR = join(repoRoot(), "resources", "mcps", "configs");

// Baseline always-on CLAUDE.md cost for a profile that hasn't been materialized
// yet. Dominated by the shared `core` persona + integrity protocol, so it's
Expand Down
7 changes: 3 additions & 4 deletions src/commands/create-profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@
*/

import { mkdir, writeFile, access } from "node:fs/promises";
import { join, resolve, dirname } from "node:path";
import { fileURLToPath } from "node:url";
import { join } from "node:path";
import { repoRoot } from "../lib/repo-root";

const REPO_ROOT = process.env.CUE_REPO_ROOT ?? process.env.SOUL_REPO_ROOT ?? resolve(dirname(fileURLToPath(import.meta.url)), "..", "..");

interface ParsedArgs {
name: string | null;
Expand Down Expand Up @@ -101,7 +100,7 @@ export async function run(args: string[]): Promise<number> {
return 1;
}

const profilesDir = process.env.CUE_PROFILES_DIR ?? join(REPO_ROOT, "profiles");
const profilesDir = process.env.CUE_PROFILES_DIR ?? join(repoRoot(), "profiles");
const profileDir = join(profilesDir, parsed.name);
const yamlPath = join(profileDir, "profile.yaml");

Expand Down
9 changes: 4 additions & 5 deletions src/commands/debug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,14 @@

import { resolve, join, dirname } from "node:path";
import { existsSync, readFileSync, lstatSync, readlinkSync } from "node:fs";
import { fileURLToPath } from "node:url";
import { homedir } from "node:os";

import { loadProfile } from "../lib/profile-loader";
import { resolveProfileForCwd } from "../lib/cwd-resolver";
import { repoRoot } from "../lib/repo-root";

const REPO_ROOT = process.env.CUE_REPO_ROOT ?? process.env.SOUL_REPO_ROOT ?? resolve(dirname(fileURLToPath(import.meta.url)), "..", "..");
const SKILLS_ROOT = join(REPO_ROOT, "resources", "skills", "skills");
const MCP_CONFIGS_DIR = join(REPO_ROOT, "resources", "mcps", "configs");
const SKILLS_ROOT = join(repoRoot(), "resources", "skills", "skills");
const MCP_CONFIGS_DIR = join(repoRoot(), "resources", "mcps", "configs");
const RUNTIME_ROOT = join(homedir(), ".config", "cue", "runtime");

export async function run(args: string[]): Promise<number> {
Expand Down Expand Up @@ -119,7 +118,7 @@ export async function run(args: string[]): Promise<number> {
}

// 4b. Rules / Commands / Hooks
const RESOURCES_ROOT = join(REPO_ROOT, "resources");
const RESOURCES_ROOT = join(repoRoot(), "resources");
let resourceIssues = 0;
for (const [kind, refs, base] of [
["Rules", profile.rules, join(RESOURCES_ROOT, "rules")],
Expand Down
7 changes: 3 additions & 4 deletions src/commands/diff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@
*/

import { readFileSync } from "node:fs";
import { join, resolve, dirname } from "node:path";
import { fileURLToPath } from "node:url";
import { join } from "node:path";

import { loadProfile } from "../lib/profile-loader";
import { resolveProfileForCwd } from "../lib/cwd-resolver";
import { repoRoot } from "../lib/repo-root";

const REPO_ROOT = process.env.CUE_REPO_ROOT ?? process.env.SOUL_REPO_ROOT ?? resolve(dirname(fileURLToPath(import.meta.url)), "..", "..");
const SKILLS_ROOT = join(REPO_ROOT, "resources", "skills", "skills");
const SKILLS_ROOT = join(repoRoot(), "resources", "skills", "skills");

function estimateTokens(text: string): number { return Math.ceil(text.length / 4); }
function getSkillTokens(id: string): number {
Expand Down
15 changes: 7 additions & 8 deletions src/commands/discover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,24 @@

import { spawnSync } from "node:child_process";
import { readFileSync, existsSync, mkdirSync, writeFileSync } from "node:fs";
import { resolve, dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import { dirname, join } from "node:path";
import { homedir } from "node:os";

import { listProfiles } from "../lib/profile-loader";
import { clusterByKeywords, clusterByEmbeddings, unclustered, type Cluster, type ClusterItem } from "../lib/cluster-skills";
import { findRealClaudeBin } from "../lib/claude-binary";
import { fetchCompanionFiles, detectSkillPath } from "../lib/companion-fetch";
import { gateFreshSkill } from "./security";
import { repoRoot } from "../lib/repo-root";

const REPO_ROOT = process.env.CUE_REPO_ROOT ?? process.env.SOUL_REPO_ROOT ?? resolve(dirname(fileURLToPath(import.meta.url)), "..", "..");
// Cache path resolved lazily so tests can redirect via XDG_CONFIG_HOME without
// re-importing the module. (Bun shares module state across test files; const
// values captured at import time wouldn't see runtime env changes.)
function cacheDir(): string {
return join(process.env.XDG_CONFIG_HOME ?? join(homedir(), ".config"), "cue", "discover");
}
function cacheFile(): string { return join(cacheDir(), "gems.json"); }
const DEFAULT_EXPORT = join(REPO_ROOT, "docs", "discovered.md");
const DEFAULT_EXPORT = join(repoRoot(), "docs", "discovered.md");

// ---------------------------------------------------------------------------
// Types
Expand Down Expand Up @@ -438,7 +437,7 @@ export function tierColorFor(score: number): string {
* Cheap enough to call per-gem (cached once per session via the closure pattern
* in renderers).
*/
export function getInstalledIn(gem: GemRepo, profilesDir = join(REPO_ROOT, "profiles")): string[] {
export function getInstalledIn(gem: GemRepo, profilesDir = join(repoRoot(), "profiles")): string[] {
if (!existsSync(profilesDir)) return [];
const hits: string[] = [];
const slugs = [gem.name.toLowerCase(), gem.full_name.toLowerCase()];
Expand Down Expand Up @@ -2179,7 +2178,7 @@ async function cmdInstall(opts: { profile?: string; minScore: number; minQuality
autoInstallClis(gem.name, { yes: opts.yes });

// Add to profile.yaml
const profileYaml = join(REPO_ROOT, "profiles", targetProfile, "profile.yaml");
const profileYaml = join(repoRoot(), "profiles", targetProfile, "profile.yaml");
if (existsSync(profileYaml)) {
const content = readFileSync(profileYaml, "utf8");
// Find the skill ID (use repo name as fallback)
Expand Down Expand Up @@ -2598,7 +2597,7 @@ async function cmdDiscoverMcps(opts: { limit: number; minScore: number; json: bo

if (opts.install) {
const targetProfile = opts.profile ?? getActiveProfile() ?? "core";
const profileYaml = join(REPO_ROOT, "profiles", targetProfile, "profile.yaml");
const profileYaml = join(repoRoot(), "profiles", targetProfile, "profile.yaml");
if (!existsSync(profileYaml)) {
process.stderr.write(` ⚠️ Profile "${targetProfile}" not found at ${profileYaml}\n`);
return 1;
Expand Down Expand Up @@ -2854,7 +2853,7 @@ Examples:
const minSize = minSizeIdx >= 0 ? parseInt(args[minSizeIdx + 1] ?? "3", 10) : 3;
const outIdx = args.indexOf("--out");
const outDir = outIdx >= 0 && args[outIdx + 1] ? args[outIdx + 1]!
: join(REPO_ROOT, ".cue-suggestions");
: join(repoRoot(), ".cue-suggestions");
const dryRun = args.includes("--dry-run");
const noClaude = args.includes("--no-claude");
const embeddings = args.includes("--embeddings");
Expand Down
13 changes: 6 additions & 7 deletions src/commands/doctor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import { readFileSync, existsSync, lstatSync, readlinkSync, readdirSync } from "node:fs";
import { readFile, writeFile, rm } from "node:fs/promises";
import { resolve, dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import { spawnSync } from "node:child_process";

import { listProfiles, loadProfile } from "../lib/profile-loader";
Expand All @@ -28,12 +27,12 @@ import { detectMissingDependencies } from "../lib/skill-dependencies";
import { shimInstalled, runInstall } from "./shell";
import { findRealClaudeBin } from "../lib/claude-binary";
import { homedir } from "node:os";
import { repoRoot } from "../lib/repo-root";

const REPO_ROOT = process.env.CUE_REPO_ROOT ?? process.env.SOUL_REPO_ROOT ?? resolve(dirname(fileURLToPath(import.meta.url)), "..", "..");
const PROFILES_DIR = process.env.CUE_PROFILES_DIR ?? join(REPO_ROOT, "profiles");
const SKILLS_ROOT = join(REPO_ROOT, "resources", "skills", "skills");
const MCP_CONFIGS_DIR = join(REPO_ROOT, "resources", "mcps", "configs");
const QUALITY_GATES_DIR = join(REPO_ROOT, "resources", "quality-gates");
const PROFILES_DIR = process.env.CUE_PROFILES_DIR ?? join(repoRoot(), "profiles");
const SKILLS_ROOT = join(repoRoot(), "resources", "skills", "skills");
const MCP_CONFIGS_DIR = join(repoRoot(), "resources", "mcps", "configs");
const QUALITY_GATES_DIR = join(repoRoot(), "resources", "quality-gates");
const RUNTIME_ROOT = join(process.env.HOME ?? "~", ".config", "cue", "runtime");

interface Issue {
Expand Down Expand Up @@ -555,7 +554,7 @@ async function runCliDoctor(profileName: string | null, json: boolean): Promise<
}

// Load the optimizer's CLI extraction logic
const SKILLS_ROOT_PATH = join(REPO_ROOT, "resources", "skills", "skills");
const SKILLS_ROOT_PATH = join(repoRoot(), "resources", "skills", "skills");
const HOME_SKILLS_PATH = join(process.env.HOME ?? "~", ".claude", "skills");

// Load profile to get skills
Expand Down
7 changes: 3 additions & 4 deletions src/commands/eval-behavior.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,15 @@
*/

import { readFileSync, } from "node:fs";
import { join, resolve, dirname, isAbsolute } from "node:path";
import { fileURLToPath } from "node:url";
import { join, isAbsolute } from "node:path";
import { homedir } from "node:os";

import { loadProfile, listProfiles } from "../lib/profile-loader";
import { resolveProfileForCwd } from "../lib/cwd-resolver";
import type { ResolvedProfile } from "../../profiles/_types";
import { repoRoot } from "../lib/repo-root";

const REPO_ROOT = process.env.CUE_REPO_ROOT ?? process.env.SOUL_REPO_ROOT ?? resolve(dirname(fileURLToPath(import.meta.url)), "..", "..");
const EVALS_ROOT = join(REPO_ROOT, "resources", "evals");
const EVALS_ROOT = join(repoRoot(), "resources", "evals");

const bold = (s: string) => `\x1b[1m${s}\x1b[0m`;
const green = (s: string) => `\x1b[32m${s}\x1b[0m`;
Expand Down
13 changes: 6 additions & 7 deletions src/commands/eval.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,20 @@
* cost-per-message and the score now use perMessage so they reflect reality.
*/

import { resolve, join, dirname, isAbsolute } from "node:path";
import { join, isAbsolute } from "node:path";
import { readFileSync, } from "node:fs";
import { fileURLToPath } from "node:url";
import { homedir } from "node:os";

import { loadProfile, listProfiles } from "../lib/profile-loader";
import { resolveProfileForCwd } from "../lib/cwd-resolver";
import { computeStats } from "../lib/analytics";
import type { ResolvedProfile } from "../../profiles/_types";
import { repoRoot } from "../lib/repo-root";

const REPO_ROOT = process.env.CUE_REPO_ROOT ?? process.env.SOUL_REPO_ROOT ?? resolve(dirname(fileURLToPath(import.meta.url)), "..", "..");
const SKILLS_ROOT = join(REPO_ROOT, "resources", "skills", "skills");
const RULES_ROOT = join(REPO_ROOT, "resources", "rules");
const COMMANDS_ROOT = join(REPO_ROOT, "resources", "commands");
const HOOKS_ROOT = join(REPO_ROOT, "resources", "hooks");
const SKILLS_ROOT = join(repoRoot(), "resources", "skills", "skills");
const RULES_ROOT = join(repoRoot(), "resources", "rules");
const COMMANDS_ROOT = join(repoRoot(), "resources", "commands");
const HOOKS_ROOT = join(repoRoot(), "resources", "hooks");

// Approximate fixed per-message cost of one hook entry in settings.json
// (matcher + command path + description). Hook scripts themselves never enter
Expand Down
Loading
Loading