Skip to content
Closed
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
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ function validateRelatedProjects(): void {
}

// Load config and validate related projects on startup
const config = getConfig();
getConfig(); // validate config on startup
validateRelatedProjects();

const profile = getProfile();
Expand Down
2 changes: 1 addition & 1 deletion src/lib/files.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { readFileSync, existsSync, readdirSync, statSync } from "fs";
import { join } from "path";
import type { DocInfo, DocMeta } from "../types.js";
import type { DocInfo } from "../types.js";

/** Single source of truth for the project directory. */
export const PROJECT_DIR = process.env.CLAUDE_PROJECT_DIR || process.cwd();
Expand Down
6 changes: 0 additions & 6 deletions src/lib/git.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { execFileSync } from "child_process";
import { PROJECT_DIR } from "./files.js";
import type { RunError } from "../types.js";

/**
* Run a git command safely using execFileSync (no shell injection).
Expand All @@ -17,7 +16,7 @@
maxBuffer: 1024 * 1024,
stdio: ["pipe", "pipe", "pipe"],
}).trim();
} catch (e: any) {

Check warning on line 19 in src/lib/git.ts

View workflow job for this annotation

GitHub Actions / build-and-test (20)

Unexpected any. Specify a different type
const timedOut = e.killed === true || e.signal === "SIGTERM";
if (timedOut) {
return `[timed out after ${opts.timeout || 10000}ms]`;
Expand All @@ -30,11 +29,6 @@
}
}

/** Convenience: run a raw command string (split on spaces). Only for simple, known-safe commands. */
function gitCmd(cmdStr: string, opts?: { timeout?: number }): string {
return run(cmdStr.split(/\s+/), opts);
}

/** Get the current branch name. */
export function getBranch(): string {
return run(["branch", "--show-current"]);
Expand Down
2 changes: 1 addition & 1 deletion src/lib/patterns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ export function matchPatterns(
patterns: CorrectionPattern[],
): CorrectionPattern[] {
if (patterns.length === 0) return [];
const promptKeywords = extractKeywords(prompt);
// keywords extracted inline below
const promptLower = prompt.toLowerCase();

return patterns.filter((p) => {
Expand Down
8 changes: 4 additions & 4 deletions src/lib/timeline-db.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import * as lancedb from "@lancedb/lancedb";
import { randomUUID } from "node:crypto";
import { readFile, writeFile, mkdir, stat } from "node:fs/promises";
import { readFile, writeFile, mkdir } from "node:fs/promises";
import { createHash } from "node:crypto";
import { homedir } from "node:os";
import { join, basename, resolve } from "node:path";
import { createEmbeddingProvider, type EmbeddingProvider, type EmbeddingConfig } from "./embeddings.js";
import type { ProjectMeta, ProjectRegistry, SearchScope } from "../types.js";
import { createEmbeddingProvider, type EmbeddingProvider } from "./embeddings.js";
import type { ProjectMeta, ProjectRegistry } from "../types.js";

// --- Types ---

Expand Down Expand Up @@ -342,7 +342,7 @@ export async function searchSemantic(
_score: 1 - (result._distance || 0),
});
}
} catch (error) {
} catch {
// Skip projects that don't exist or have issues
continue;
}
Expand Down
2 changes: 1 addition & 1 deletion src/tools/audit-workspace.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { run } from "../lib/git.js";
import { readIfExists, findWorkspaceDocs } from "../lib/files.js";
import { findWorkspaceDocs } from "../lib/files.js";

/** Extract top-level work areas from file paths generically */
function detectWorkAreas(files: string[]): Set<string> {
Expand Down
2 changes: 1 addition & 1 deletion src/tools/checkpoint.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { z } from "zod";
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { writeFileSync, existsSync, mkdirSync } from "fs";
import { join, dirname } from "path";
import { join } from "path";
import { run, getBranch, getStatus, getLastCommit, getStagedFiles } from "../lib/git.js";
import { PROJECT_DIR } from "../lib/files.js";
import { appendLog, now } from "../lib/state.js";
Expand Down
35 changes: 1 addition & 34 deletions src/tools/generate-scorecard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ function clamp(v: number): number {

const PATH_RE = /(?:\/[\w./-]+\.\w{1,6}|\b\w+\.\w{2,6}\b)/;
const FILE_EXT_RE = /\.\b(?:ts|tsx|js|jsx|py|rs|go|rb|java|c|cpp|h|css|scss|html|json|yaml|yml|toml|md|sql|sh)\b/;
const CORRECTION_PATTERNS = [/\bno\b/i, /\bwrong\b/i, /\bnot that\b/i, /\bi meant\b/i, /\bactually\b/i, /\binstead\b/i, /\bundo\b/i, /\brevert\b/i];
// Correction patterns detected inline in parseSession below

interface ParsedSession {
id: string;
Expand Down Expand Up @@ -421,39 +421,6 @@ function computeScorecard(

// ── Markdown Output ────────────────────────────────────────────────────────

function toMarkdown(sc: Scorecard): string {
const lines: string[] = [];
lines.push(`# 📊 Prompt Discipline Scorecard`);
lines.push(`**Project:** ${sc.project} | **Period:** ${sc.period} (${sc.date}) | **Overall: ${sc.overallGrade} (${sc.overall}/100)**\n`);

lines.push(`## Category Scores`);
lines.push(`| # | Category | Score | Grade |`);
lines.push(`|---|----------|-------|-------|`);
sc.categories.forEach((c, i) => {
lines.push(`| ${i + 1} | ${c.name} | ${c.score} | ${c.grade} |`);
});

lines.push(`\n## Highlights`);
lines.push(`- 🏆 **Best:** ${sc.highlights.best.name} (${sc.highlights.best.grade}) — ${sc.highlights.best.evidence}`);
lines.push(`- ⚠️ **Worst:** ${sc.highlights.worst.name} (${sc.highlights.worst.grade}) — ${sc.highlights.worst.evidence}`);

lines.push(`\n## Detailed Breakdown`);
sc.categories.forEach((c, i) => {
lines.push(`\n### ${i + 1}. ${c.name} — ${c.grade} (${c.score}/100)`);
lines.push(`Evidence: ${c.evidence}`);
if (c.examples?.bad?.length) {
lines.push(`\nExamples of vague follow-ups:`);
c.examples.bad.forEach((e) => lines.push(`- ❌ "${e}"`));
}
if (c.examples?.good?.length) {
lines.push(`\nExamples of specific follow-ups:`);
c.examples.good.forEach((e) => lines.push(`- ✅ "${e}"`));
}
});

return lines.join("\n");
}

// ── HTML / PDF Output ──────────────────────────────────────────────────────

function gradeColor(grade: string): string {
Expand Down
2 changes: 0 additions & 2 deletions src/tools/onboard-project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ import * as path from "path";
import {
insertEvents,
getLastIndexedTimestamp,
listIndexedProjects,
getEventsTable,
registerProject,
loadProjectMeta,
saveProjectMeta
} from "../lib/timeline-db.js";
Expand Down
8 changes: 4 additions & 4 deletions src/tools/preflight-check.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
// Unified preflight_check — single entry point that triages and chains tools
import { z } from "zod";
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { triagePrompt, type TriageLevel, type TriageResult } from "../lib/triage.js";
import { triagePrompt, type TriageLevel } from "../lib/triage.js";
import { existsSync, statSync } from "fs";
import { resolve } from "path";
import { PROJECT_DIR } from "../lib/files.js";
import { run, getBranch, getStatus, getRecentCommits, getDiffFiles, getStagedFiles } from "../lib/git.js";
import { getBranch, getStatus, getRecentCommits } from "../lib/git.js";
import { now } from "../lib/state.js";
import { findWorkspaceDocs } from "../lib/files.js";
import { getConfig } from "../lib/config.js";
import { searchSemantic } from "../lib/timeline-db.js";
import { basename, join } from "path";
import { loadPatterns, matchPatterns, formatPatternMatches } from "../lib/patterns.js";
import { basename } from "path";
import { loadPatterns, matchPatterns } from "../lib/patterns.js";

// ---------------------------------------------------------------------------
// Helpers
Expand Down
1 change: 0 additions & 1 deletion src/tools/scan-sessions.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { z } from "zod";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import * as fs from "fs";
import * as path from "path";
import { findSessionDirs, findSessionFiles } from "../lib/session-parser.js";

interface SessionInfo {
Expand Down
4 changes: 2 additions & 2 deletions src/tools/scope-work.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// CATEGORY 1: scope_work — Plans
import { z } from "zod";
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { run, getBranch, getRecentCommits, getStatus } from "../lib/git.js";
import { run, getBranch, getRecentCommits } from "../lib/git.js";
import { readIfExists, findWorkspaceDocs, PROJECT_DIR } from "../lib/files.js";
import { searchSemantic } from "../lib/timeline-db.js";
import { getRelatedProjects } from "../lib/config.js";
import { now } from "../lib/state.js";
import { existsSync } from "fs";
import { join, normalize, resolve, basename } from "path";
import { join, resolve, basename } from "path";
import { loadAllContracts, searchContracts, formatContracts } from "../lib/contracts.js";

const STOP_WORDS = new Set([
Expand Down
3 changes: 1 addition & 2 deletions src/tools/sequence-tasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { run } from "../lib/git.js";
import { now } from "../lib/state.js";
import { PROJECT_DIR } from "../lib/files.js";
import { existsSync } from "fs";
import { join, resolve } from "path";
import { resolve } from "path";

type Cat = "schema" | "config" | "api" | "ui" | "test" | "other";

Expand Down
2 changes: 1 addition & 1 deletion src/tools/token-audit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { z } from "zod";
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { run } from "../lib/git.js";
import { readIfExists, findWorkspaceDocs, PROJECT_DIR } from "../lib/files.js";
import { loadState, saveState, now, STATE_DIR } from "../lib/state.js";
import { saveState, now, STATE_DIR } from "../lib/state.js";
import { readFileSync, existsSync, statSync } from "fs";
import { join } from "path";

Expand Down
Loading