refactor: move cache to .cache/pi-project-map/ (hidden by default)
- Change cache location from .pi-project-map/cache/ to .cache/pi-project-map/ - Cache is now hidden by default (dot directory) - Add .cache/ to .gitignore - Remove committed .pi-project-map/cache/ from repo
This commit is contained in:
@@ -7,3 +7,5 @@ coverage/
|
||||
.pi-map.md
|
||||
# Local Pi runtime state
|
||||
.atl/
|
||||
.pi
|
||||
.cache/
|
||||
|
||||
Vendored
-62
@@ -1,62 +0,0 @@
|
||||
{
|
||||
"25c2db9d6c4c2c511bec4a736f5adf77423be6011bbedd916fb55003d059b4e3": {
|
||||
"result": "PURPOSE: Test file\nDEPS: none\nCONCEPTS: testing",
|
||||
"ts": 1781105452802
|
||||
},
|
||||
"889300ab1d0afe082d820fdd9150229625c3ab69b3b84c2ca65d67479be388cc": {
|
||||
"result": "PURPOSE: Test file\nDEPS: none\nCONCEPTS: testing",
|
||||
"ts": 1781105452841
|
||||
},
|
||||
"585c5da8de102beb6a9906f0e3f07a134b5392bed52fc1a0aaef989e69aa66b6": {
|
||||
"result": "PURPOSE: Test file\nDEPS: none\nCONCEPTS: testing",
|
||||
"ts": 1781105452845
|
||||
},
|
||||
"a6f92e629a4c341fe1e10f92ef923c54002b8a79ec3bedb0b9079bc7aca4e2e0": {
|
||||
"result": "PURPOSE: Test file\nDEPS: none\nCONCEPTS: testing",
|
||||
"ts": 1781105452846
|
||||
},
|
||||
"a6c149b54aec4ced46eb38d6faf1f20ec62fd2f9a2f2dcb6a15c4f339dfb5f1e": {
|
||||
"result": "PURPOSE: Test file\nDEPS: none\nCONCEPTS: testing",
|
||||
"ts": 1781105452846
|
||||
},
|
||||
"4eda95f6452551a12d5b434e284c2e539ce57e0206d5ffa49609f4fa8354a966": {
|
||||
"result": "PURPOSE: Test file\nDEPS: none\nCONCEPTS: testing",
|
||||
"ts": 1781105452846
|
||||
},
|
||||
"510456d000664badf3cbec9f70c80769a119a590e84b1971e49ac5728882a699": {
|
||||
"result": "PURPOSE: Test file\nDEPS: none\nCONCEPTS: testing",
|
||||
"ts": 1781105452847
|
||||
},
|
||||
"b0f5449d50fda0b5c0cf47103188df2d4339b047e1e03cab7a15a431f2990185": {
|
||||
"result": "PURPOSE: Test file\nDEPS: none\nCONCEPTS: testing",
|
||||
"ts": 1781105452848
|
||||
},
|
||||
"eebe9a750792a3d802c6868f32ac264d44ef193a6f1940c4ad5e715b6e31074a": {
|
||||
"result": "PURPOSE: Test file\nDEPS: none\nCONCEPTS: testing",
|
||||
"ts": 1781105452848
|
||||
},
|
||||
"4958b5d7ec5b4c975bb1e2972519aff5fbd94cb7342be4f8dd854a5c7353bd26": {
|
||||
"result": "PURPOSE: Test file\nDEPS: none\nCONCEPTS: testing",
|
||||
"ts": 1781105452849
|
||||
},
|
||||
"389a385ef4fc5d1d253253fa3c931c505c7fbcca68db4ebe6b34392b3ca32d65": {
|
||||
"result": "PURPOSE: Test file\nDEPS: none\nCONCEPTS: testing",
|
||||
"ts": 1781105452849
|
||||
},
|
||||
"879d2eff31eaf101d30de95e0e2df1c1a3a305c4e3b0515a22c85969af49ff25": {
|
||||
"result": "PURPOSE: Test file\nDEPS: none\nCONCEPTS: testing",
|
||||
"ts": 1781105452947
|
||||
},
|
||||
"c2f0a91350b7f5e11a95848c4d806e49d2017862acbc43afb1dd52a5e73c0b24": {
|
||||
"result": "PURPOSE: Test file\nDEPS: none\nCONCEPTS: testing",
|
||||
"ts": 1781105452948
|
||||
},
|
||||
"037ecd1db38c230c248787e60fd7bfc0cb0101b187b59535b6e7483be762d350": {
|
||||
"result": "PURPOSE: Test file\nDEPS: none\nCONCEPTS: testing",
|
||||
"ts": 1781105452950
|
||||
},
|
||||
"b5d546753d33709dff508a6f2c2e547f432267fbb05b68d3da74fa5f7bda9f7a": {
|
||||
"result": "PURPOSE: Test file\nDEPS: none\nCONCEPTS: testing",
|
||||
"ts": 1781105452953
|
||||
}
|
||||
}
|
||||
Vendored
+64
@@ -202,5 +202,69 @@
|
||||
"64f5ab73ff71a9c41639f3c8a5e248387a01e27a9612f0ed2b682708557f6a27": {
|
||||
"result": "PURPOSE: Unit tests for a Pi extension that registers project map tools and lifecycle event handlers.\nDEPS: vitest, fs, path, os, @mariozechner/pi-coding-agent, typebox, @mariozechner/pi-ai, ../pi-extension.js\nCONCEPTS: unit testing, mocking with vi.mock, dependency injection, temporary filesystem fixtures, tool registration testing, event handler testing",
|
||||
"ts": 1781101463953
|
||||
},
|
||||
"935ebdfde630eef58b7ce919770361a192cb568352bdc4f6feb73e49712435ec": {
|
||||
"result": "PURPOSE: Auto-generated dependency lock file that records exact versions of all npm packages for the \"pi-project-map\" project to ensure reproducible installs\nDEPS: npm, node, esbuild, eslint, typescript, vitest, openai, tree-sitter, tree-sitter-python, tree-sitter-typescript, p-limit, picocolors, ignore\nCONCEPTS: dependency resolution, version locking, reproducible builds, transitive dependencies, semantic versioning, package management",
|
||||
"ts": 1781105803170
|
||||
},
|
||||
"c02b509bba0bcfa201a834375562034eecad9920aef5b067f9a93387ce2b342e": {
|
||||
"result": "PURPOSE: Registers four Pi extension tools (project_map_init, project_map_patch, project_map_validate, project_map_reinit) for managing .pi-map.md project analysis files, plus session lifecycle hooks for auto-detection and maintenance hints.\nDEPS: @mariozechner/pi-coding-agent, typebox, fs, path, ./src/index.js, ./src/llm/llm-client.js, ./src/llm/llm-error.js\nCONCEPTS: Extension API registration, LLM client abstraction, file system traversal, schema validation with TypeBox, async tool execution, event hooks (session_start, before_agent_start), progress callbacks, error handling with custom error types",
|
||||
"ts": 1781105804655
|
||||
},
|
||||
"c95b6b5a1bdb3154e1570d6d7d6375d7e8f141ece9a26e3ce3ccf3315fbb3595": {
|
||||
"result": "PURPOSE: Stores cached LLM analysis results keyed by content hash with timestamps to avoid redundant API calls\nDEPS: none\nCONCEPTS: caching, content-addressable storage, memoization, key-value store, hash-based lookup",
|
||||
"ts": 1781105823217
|
||||
},
|
||||
"5392cfc86e14d048ff4aa8472945d7ff1254ca160ca656d6a7a02cdfc2931240": {
|
||||
"result": "PURPOSE: Stores cached LLM analysis results keyed by SHA-256 content hashes with timestamps for a project mapping tool\nDEPS: none (self-contained JSON cache file)\nCONCEPTS: content-addressable storage, caching, JSON serialization, SHA-256 hashing, timestamp tracking, key-value store",
|
||||
"ts": 1781105832833
|
||||
},
|
||||
"08c8a9ec61a988cfb22e6cbe381d66ed2b2a9831ea033073a63767fb11d3054c": {
|
||||
"result": "PURPOSE: Validates and optionally repairs `.pi-map.md` files against actual project state by detecting missing maps, orphaned entries, dirty markers, and stale export signatures.\nDEPS: fs, path, ./discover.js, ./format.js, ./ast/ast-extract.js, ./init.js\nCONCEPTS: AST analysis, set comparison, discrepancy detection, dry-run vs fix modes, directory iteration",
|
||||
"ts": 1781105865731
|
||||
},
|
||||
"f81a700850a8ab1067d1329af2675464e6435137e278ab8d62fcd5fc0bc5a1c4": {
|
||||
"result": "PURPOSE: Patches a `.pi-map.md` file for a given source file, using full rewrite for small packages or section-level merging of LLM and AST extracted data for larger packages.\nDEPS: path, fs, ./format.js, ./llm/llm-extract.js, ./ast/ast-extract.js, ./merge.js, ./init.js, ./llm/llm-client.js\nCONCEPTS: conditional logic, file I/O, async/await, AST extraction, LLM extraction, data merging, threshold-based strategy pattern, in-place array mutation",
|
||||
"ts": 1781105867062
|
||||
},
|
||||
"9f9cdf5a97d15f2ada69a3290288acbbca55693293e64eaa54ed68a3b69085dd": {
|
||||
"result": "PURPOSE: Orchestrates project initialization by discovering directories, extracting file metadata via LLM and AST analysis, and generating `.pi-map.md` documentation files for each package.\nDEPS: fs, path, discover.js, format.js, llm/llm-extract.js, ast/ast-extract.js, merge.js, llm/llm-batch.js, llm/llm-client.js\nCONCEPTS: async/await, concurrency control, batch processing with retry logic, progress callbacks, dependency injection, file I/O, data merging from multiple sources",
|
||||
"ts": 1781105867332
|
||||
},
|
||||
"b84477286885b2bed506b8b4b80b9a9a1ca0cb3b351bcd72f938559e55b152bc": {
|
||||
"result": "PURPOSE: CLI entry point for a project mapping tool that generates, patches, validates, and regenerates `.pi-map.md` files using LLM-powered analysis.\nDEPS: picocolors, process, ../init.js, ../patch.js, ../validate.js, ../discover.js, ../llm/llm-client.js, ../config.js, ../package.json\nCONCEPTS: CLI argument parsing, command dispatch pattern, async/await, error handling with custom error classes, LLM client abstraction, configuration loading, process exit codes, pluralization formatting",
|
||||
"ts": 1781105883128
|
||||
},
|
||||
"cb84ff08ab46a12f7a1fb49c7c3874743d4c38dd76d22c82ccea424e295ed929": {
|
||||
"result": "PURPOSE: Extracts structured metadata (purpose, dependencies, concepts) from source files and packages using LLM prompts, with binary detection, size limits, and caching.\nDEPS: fs, crypto, path, llm-client.js, llm-cache.js, llm-error.js\nCONCEPTS: LLM prompt engineering, structured output parsing, content hashing, binary file detection, caching, context window management, token budgeting",
|
||||
"ts": 1781105897002
|
||||
},
|
||||
"15cf6bdf05a57be59d4729d5095808645f6c6883d2d1e8615b3b5ce12d774a81": {
|
||||
"result": "PURPOSE: Unit tests for an LLM response caching module that stores and retrieves string results by hash key in a JSON file.\nDEPS: vitest, fs, path, os, ../src/llm/llm-cache.js\nCONCEPTS: unit testing, file-based caching, test isolation with beforeEach/afterEach cleanup, temporary file storage",
|
||||
"ts": 1781105907011
|
||||
},
|
||||
"2c776feaa98a5da6e1e68f908d855479994633779a7b6987f3675f0052c2cd98": {
|
||||
"result": "PURPOSE: Tests retry logic and parallel file processing utilities for LLM batch operations.\nDEPS: vitest, ../src/llm/llm-batch.js, ../src/llm-error.js\nCONCEPTS: unit testing, retry patterns, concurrency control, async/await, error handling",
|
||||
"ts": 1781105907677
|
||||
},
|
||||
"6198821ec6dd5417980e89ed44488c1d8bd78616a8396186acaed23bb331ad8a": {
|
||||
"result": "PURPOSE: Tests the AST extraction functionality for parsing TypeScript exports, imports, and unsupported file types.\nDEPS: vitest, fs, path, os, ast-extract.js\nCONCEPTS: unit testing, temporary file creation, async/await, null safety with non-null assertion operator",
|
||||
"ts": 1781105907686
|
||||
},
|
||||
"9f4d46b86a312ada127f0d5d295c4933959c42b8797e67a51abeed90bb44d468": {
|
||||
"result": "PURPOSE: Integration tests for a project mapping tool that verifies init, patch, and validate functionality using temporary directories and mock LLM clients.\nDEPS: vitest, fs, path, os, ../src/init.js, ../src/patch.js, ../src/validate.js, ./mock-llm.js\nCONCEPTS: integration testing, temporary filesystem fixtures, mock objects, setup/teardown hooks, async/await",
|
||||
"ts": 1781105908326
|
||||
},
|
||||
"d74151fa0b1c6e8dfdb5987527a624466beb4e5b6aecd1c16f57418046613c2d": {
|
||||
"result": "PURPOSE: Tests the extractFileLLM function's behavior with mock LLM clients, including parsing responses, handling missing clients, and skipping large/binary files.\nDEPS: vitest, fs, path, os, ../src/llm/llm-extract.js, ../src/llm/llm-client.js\nCONCEPTS: unit testing, mocking, async/await, temporary file fixtures, dependency injection, parser validation, edge case handling",
|
||||
"ts": 1781105909833
|
||||
},
|
||||
"5694eddea81e0978855baf756c906337a6edf1c2f6f1615ab31a66d2aeb56750": {
|
||||
"result": "PURPOSE: Provides mock LLM client factories for testing that return predefined analysis strings\nDEPS: ../src/llm/llm-client.js\nCONCEPTS: mocking, factory functions, dependency injection, testing",
|
||||
"ts": 1781105910171
|
||||
},
|
||||
"bd21b840465df9c0972a36b707e13ed712a3186a39312876178415d73250956a": {
|
||||
"result": "PURPOSE: Integration tests for LLM client functionality including Kimi API calls, file/package extraction, caching, parallel processing, and error handling\nDEPS: vitest, fs, path, os, ../src/llm/llm-client.js, ../src/llm/llm-extract.js, ../src/llm/llm-batch.js\nCONCEPTS: integration testing, environment variable management, temporary file system operations, LLM API mocking/spying, caching validation, concurrency control, error handling for missing credentials, test skipping based on environment conditions",
|
||||
"ts": 1781105911634
|
||||
}
|
||||
}
|
||||
@@ -7,8 +7,8 @@ import {
|
||||
} from "fs";
|
||||
import { join } from "path";
|
||||
|
||||
const DEFAULT_CACHE_SUBDIR = ".pi-project-map";
|
||||
const DEFAULT_CACHE_FILE = "cache/llm-cache.json";
|
||||
const DEFAULT_CACHE_SUBDIR = ".cache/pi-project-map";
|
||||
const DEFAULT_CACHE_FILE = "llm-cache.json";
|
||||
|
||||
interface CacheEntry {
|
||||
result: string;
|
||||
|
||||
+82
-15
@@ -23,15 +23,58 @@ const CHARS_PER_TOKEN = 4; // approximate for ASCII
|
||||
|
||||
// Known binary extensions — skip without reading content
|
||||
const BINARY_EXTENSIONS = new Set([
|
||||
".png", ".jpg", ".jpeg", ".gif", ".bmp", ".webp", ".ico", ".svgz",
|
||||
".mp3", ".mp4", ".avi", ".mov", ".mkv", ".flv", ".wmv",
|
||||
".wav", ".ogg", ".flac", ".aac", ".wma",
|
||||
".zip", ".tar", ".gz", ".bz2", ".xz", ".7z", ".rar",
|
||||
".exe", ".dll", ".so", ".dylib", ".bin",
|
||||
".pdf", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx",
|
||||
".wasm", ".class", ".jar", ".o", ".a",
|
||||
".ttf", ".otf", ".woff", ".woff2", ".eot",
|
||||
".db", ".sqlite", ".sqlite3",
|
||||
".png",
|
||||
".jpg",
|
||||
".jpeg",
|
||||
".gif",
|
||||
".bmp",
|
||||
".webp",
|
||||
".ico",
|
||||
".svgz",
|
||||
".mp3",
|
||||
".mp4",
|
||||
".avi",
|
||||
".mov",
|
||||
".mkv",
|
||||
".flv",
|
||||
".wmv",
|
||||
".wav",
|
||||
".ogg",
|
||||
".flac",
|
||||
".aac",
|
||||
".wma",
|
||||
".zip",
|
||||
".tar",
|
||||
".gz",
|
||||
".bz2",
|
||||
".xz",
|
||||
".7z",
|
||||
".rar",
|
||||
".exe",
|
||||
".dll",
|
||||
".so",
|
||||
".dylib",
|
||||
".bin",
|
||||
".pdf",
|
||||
".doc",
|
||||
".docx",
|
||||
".xls",
|
||||
".xlsx",
|
||||
".ppt",
|
||||
".pptx",
|
||||
".wasm",
|
||||
".class",
|
||||
".jar",
|
||||
".o",
|
||||
".a",
|
||||
".ttf",
|
||||
".otf",
|
||||
".woff",
|
||||
".woff2",
|
||||
".eot",
|
||||
".db",
|
||||
".sqlite",
|
||||
".sqlite3",
|
||||
]);
|
||||
|
||||
function isBinaryFile(filePath: string): boolean {
|
||||
@@ -77,7 +120,11 @@ ${content}
|
||||
`;
|
||||
}
|
||||
|
||||
function parseFileResponse(response: string): { purpose: string; deps: string[]; concepts: string[] } {
|
||||
function parseFileResponse(response: string): {
|
||||
purpose: string;
|
||||
deps: string[];
|
||||
concepts: string[];
|
||||
} {
|
||||
const lines = response.split("\n");
|
||||
let purpose = "";
|
||||
let deps: string[] = [];
|
||||
@@ -89,18 +136,35 @@ function parseFileResponse(response: string): { purpose: string; deps: string[];
|
||||
purpose = trimmed.slice("PURPOSE:".length).trim();
|
||||
} else if (trimmed.startsWith("DEPS:")) {
|
||||
const depsStr = trimmed.slice("DEPS:".length).trim();
|
||||
deps = depsStr === "none" ? [] : depsStr.split(",").map((s) => s.trim()).filter(Boolean);
|
||||
deps =
|
||||
depsStr === "none"
|
||||
? []
|
||||
: depsStr
|
||||
.split(",")
|
||||
.map((s) => s.trim())
|
||||
.filter(Boolean);
|
||||
} else if (trimmed.startsWith("CONCEPTS:")) {
|
||||
const conceptsStr = trimmed.slice("CONCEPTS:".length).trim();
|
||||
concepts = conceptsStr === "none" ? [] : conceptsStr.split(",").map((s) => s.trim()).filter(Boolean);
|
||||
concepts =
|
||||
conceptsStr === "none"
|
||||
? []
|
||||
: conceptsStr
|
||||
.split(",")
|
||||
.map((s) => s.trim())
|
||||
.filter(Boolean);
|
||||
}
|
||||
}
|
||||
|
||||
return { purpose, deps, concepts };
|
||||
}
|
||||
|
||||
function buildPackagePrompt(relativePath: string, fileSummaries: { name: string; purpose: string }[]): string {
|
||||
const filesList = fileSummaries.map((f) => `- ${f.name}: ${f.purpose}`).join("\n");
|
||||
function buildPackagePrompt(
|
||||
relativePath: string,
|
||||
fileSummaries: { name: string; purpose: string }[],
|
||||
): string {
|
||||
const filesList = fileSummaries
|
||||
.map((f) => `- ${f.name}: ${f.purpose}`)
|
||||
.join("\n");
|
||||
return `Analyze this code package/directory. Respond in this exact format (one line each):
|
||||
ROLE: <concise one-sentence description of this package's role in the project>
|
||||
ARCH: <concise description of architecture/patterns used in this package>
|
||||
@@ -111,7 +175,10 @@ ${filesList}
|
||||
`;
|
||||
}
|
||||
|
||||
function parsePackageResponse(response: string): { role: string; arch: string } {
|
||||
function parsePackageResponse(response: string): {
|
||||
role: string;
|
||||
arch: string;
|
||||
} {
|
||||
const lines = response.split("\n");
|
||||
let role = "";
|
||||
let arch = "";
|
||||
|
||||
Reference in New Issue
Block a user