UNPKG

@fission-ai/openspec

Version:

AI-native system for spec-driven development

102 lines 3.1 kB
import { getActiveChangeIds, getSpecIds } from '../../utils/item-discovery.js'; /** * Provides dynamic completion suggestions for OpenSpec items (changes and specs). * Implements a 2-second cache to avoid excessive file system operations during * tab completion. */ export class CompletionProvider { cacheTTLMs; projectRoot; cacheTTL; changeCache = null; specCache = null; /** * Creates a new completion provider * * @param cacheTTLMs - Cache time-to-live in milliseconds (default: 2000ms) * @param projectRoot - Project root directory (default: process.cwd()) */ constructor(cacheTTLMs = 2000, projectRoot = process.cwd()) { this.cacheTTLMs = cacheTTLMs; this.projectRoot = projectRoot; this.cacheTTL = cacheTTLMs; } /** * Get all active change IDs for completion * * @returns Array of change IDs */ async getChangeIds() { const now = Date.now(); // Check if cache is valid if (this.changeCache && now - this.changeCache.timestamp < this.cacheTTL) { return this.changeCache.data; } // Fetch fresh data const changeIds = await getActiveChangeIds(this.projectRoot); // Update cache this.changeCache = { data: changeIds, timestamp: now, }; return changeIds; } /** * Get all spec IDs for completion * * @returns Array of spec IDs */ async getSpecIds() { const now = Date.now(); // Check if cache is valid if (this.specCache && now - this.specCache.timestamp < this.cacheTTL) { return this.specCache.data; } // Fetch fresh data const specIds = await getSpecIds(this.projectRoot); // Update cache this.specCache = { data: specIds, timestamp: now, }; return specIds; } /** * Get both change and spec IDs for completion * * @returns Object with changeIds and specIds arrays */ async getAllIds() { const [changeIds, specIds] = await Promise.all([ this.getChangeIds(), this.getSpecIds(), ]); return { changeIds, specIds }; } /** * Clear all cached data */ clearCache() { this.changeCache = null; this.specCache = null; } /** * Get cache statistics for debugging * * @returns Cache status information */ getCacheStats() { const now = Date.now(); return { changeCache: { valid: this.changeCache !== null && now - this.changeCache.timestamp < this.cacheTTL, age: this.changeCache ? now - this.changeCache.timestamp : undefined, }, specCache: { valid: this.specCache !== null && now - this.specCache.timestamp < this.cacheTTL, age: this.specCache ? now - this.specCache.timestamp : undefined, }, }; } } //# sourceMappingURL=completion-provider.js.map