@vibeship/devtools
Version:
Comprehensive markdown-based project management system with AI capabilities for Next.js applications
564 lines (553 loc) • 13.9 kB
TypeScript
import * as fs from 'fs/promises';
import { V as VibeshipConfig } from './types-ChLtbM8s.js';
interface ServerConfig {
port?: number;
host?: string;
apiPrefix?: string;
}
interface FileInfo {
path: string;
content: string;
stats: {
size: number;
modified: Date;
};
}
interface ScanOptions {
paths?: string[];
include?: string[];
exclude?: string[];
}
interface ScanProgress {
current: number;
total: number;
currentPath: string;
filesFound: number;
}
interface TaskScanResult {
files: number;
tasks: number;
duration: number;
}
interface APIResponse<T = any> {
success: boolean;
data?: T;
error?: string;
}
interface ErrorResponse {
error: string;
code?: string;
details?: any;
}
interface CacheEntry<T> {
data: T;
timestamp: number;
ttl: number;
}
declare class FileScanner {
private config;
private pathValidator;
private progressCallback?;
constructor(config: VibeshipConfig);
/**
* Scan for files matching the configured patterns
*/
scan(options?: ScanOptions): Promise<string[]>;
/**
* Scan with detailed file information
*/
scanWithInfo(options?: ScanOptions): Promise<FileInfo[]>;
/**
* Read a file with validation
*/
readFile(filePath: string): Promise<string>;
/**
* Check if a file exists
*/
exists(filePath: string): Promise<boolean>;
/**
* Get file stats
*/
getStats(filePath: string): Promise<Awaited<ReturnType<typeof fs.stat>>>;
/**
* Set progress callback for long operations
*/
onProgress(callback: (progress: ScanProgress) => void): void;
/**
* Get supported file extensions from include patterns
*/
getSupportedExtensions(): string[];
}
interface Task {
id: string;
type: 'TODO' | 'FIXME' | 'HACK' | 'NOTE' | 'BUG' | 'OPTIMIZE' | 'REFACTOR';
text: string;
file: string;
line: number;
column: number;
priority?: 'low' | 'medium' | 'high';
assignee?: string;
date?: string;
context?: string;
metadata?: Record<string, any>;
}
interface TaskPattern {
pattern: RegExp;
priority?: 'low' | 'medium' | 'high';
}
interface ExtractionOptions {
customPatterns?: Record<string, TaskPattern>;
includeContext?: boolean;
contextLines?: number;
parseMetadata?: boolean;
}
declare class TaskExtractor {
private defaultPatterns;
/**
* Extract tasks from content
*/
extract(content: string, filePath: string, options?: ExtractionOptions): Task[];
/**
* Extract metadata from task text
* Format: TODO(assignee): text [priority:high] [due:2024-01-01] {key:value}
*/
private extractMetadata;
/**
* Get context lines around a task
*/
private getContext;
/**
* Extract tasks from multiple files
*/
extractFromFiles(files: Array<{
path: string;
content: string;
}>, options?: ExtractionOptions): Promise<Task[]>;
/**
* Group tasks by type
*/
groupByType(tasks: Task[]): Record<string, Task[]>;
/**
* Group tasks by file
*/
groupByFile(tasks: Task[]): Record<string, Task[]>;
/**
* Filter tasks by priority
*/
filterByPriority(tasks: Task[], priority: 'low' | 'medium' | 'high'): Task[];
/**
* Sort tasks by various criteria
*/
sortTasks(tasks: Task[], by: 'priority' | 'type' | 'file' | 'line'): Task[];
}
interface ParsedMarkdown {
content: string;
data: Record<string, any>;
excerpt?: string;
toc?: TableOfContentsItem[];
wordCount?: number;
readingTime?: number;
}
interface TableOfContentsItem {
id: string;
text: string;
level: number;
children: TableOfContentsItem[];
}
interface MarkdownSection {
id: string;
title: string;
content: string;
level: number;
}
interface MarkdownParserOptions {
excerpt?: boolean;
excerptSeparator?: string;
generateTOC?: boolean;
calculateStats?: boolean;
extractSections?: boolean;
}
declare class MarkdownParser {
private defaultOptions;
/**
* Parse markdown content with frontmatter
*/
parse(content: string, options?: MarkdownParserOptions): ParsedMarkdown;
/**
* Extract all headings with hierarchy
*/
extractHeadings(content: string): Array<{
text: string;
level: number;
id: string;
}>;
/**
* Generate table of contents with nested structure
*/
generateTableOfContents(content: string): TableOfContentsItem[];
/**
* Extract sections by headings
*/
extractSections(content: string): MarkdownSection[];
/**
* Extract links from markdown
*/
extractLinks(content: string): Array<{
text: string;
url: string;
title?: string;
}>;
/**
* Extract reference link definitions
*/
private extractReferenceDefinitions;
/**
* Extract code blocks
*/
extractCodeBlocks(content: string): Array<{
lang?: string;
code: string;
}>;
/**
* Calculate word count and reading time
*/
calculateStats(content: string): {
wordCount: number;
readingTime: number;
};
/**
* Create URL-friendly slug from text
*/
private createSlug;
/**
* Parse markdown table
*/
parseTables(content: string): Array<{
headers: string[];
rows: string[][];
}>;
/**
* Convert markdown to plain text
*/
toPlainText(content: string): string;
/**
* Generate a content hash for caching
*/
generateHash(content: string): string;
}
interface PathValidatorOptions {
allowSymlinks?: boolean;
maxDepth?: number;
blockPatterns?: RegExp[];
}
declare class PathValidator {
private allowedPaths;
private normalizedAllowedPaths;
private options;
constructor(allowedPaths: string[], options?: PathValidatorOptions);
/**
* Validate if a path is safe and allowed
*/
isValid(filePath: string): boolean;
/**
* Check for path traversal attempts
*/
private hasPathTraversal;
/**
* Check if path matches blocked patterns
*/
private isBlockedPattern;
/**
* Sanitize a file path for safe usage
*/
sanitize(filePath: string): string;
/**
* Get the relative path from allowed base
*/
getRelativePath(filePath: string): string | null;
/**
* Add a new allowed path
*/
addAllowedPath(newPath: string): void;
/**
* Remove an allowed path
*/
removeAllowedPath(removePath: string): void;
}
interface RateLimiterOptions {
windowMs: number;
maxRequests: number;
keyGenerator?: (context: any) => string;
skipSuccessfulRequests?: boolean;
skipFailedRequests?: boolean;
onLimitReached?: (identifier: string, info: RateLimitInfo) => void;
}
interface RateLimitInfo {
limit: number;
current: number;
remaining: number;
resetTime: number;
retryAfter: number;
}
declare class RateLimiter {
private options;
private requests;
private cleanupInterval?;
constructor(options: RateLimiterOptions);
/**
* Check if a request is allowed
*/
isAllowed(identifier: string, context?: any): boolean;
/**
* Get current rate limit info for an identifier
*/
getInfo(identifier: string): RateLimitInfo;
/**
* Reset rate limit for an identifier
*/
reset(identifier: string): void;
/**
* Reset all rate limits
*/
resetAll(): void;
/**
* Record a request result (for conditional limiting)
*/
recordResult(identifier: string, success: boolean): void;
/**
* Clean up old entries
*/
private cleanup;
/**
* Get statistics about current rate limiting
*/
getStats(): {
totalIdentifiers: number;
blockedIdentifiers: number;
totalRequests: number;
};
/**
* Destroy the rate limiter and clean up resources
*/
destroy(): void;
}
interface CacheOptions {
ttl: number;
maxSize?: number;
updateOnGet?: boolean;
onEvict?: (key: string, value: any) => void;
}
interface CacheStats {
entries: number;
hits: number;
misses: number;
evictions: number;
size: number;
}
declare class CacheManager {
private cache;
private stats;
private cleanupInterval?;
private defaultOptions;
constructor(options?: Partial<CacheOptions>);
/**
* Set a value in the cache
*/
set<T>(key: string, value: T, options?: Partial<CacheOptions>): void;
/**
* Get a value from the cache
*/
get<T>(key: string, options?: {
updateOnGet?: boolean;
}): T | undefined;
/**
* Get or set a value (memoization helper)
*/
getOrSet<T>(key: string, factory: () => Promise<T>, options?: Partial<CacheOptions>): Promise<T>;
/**
* Check if key exists and is not expired
*/
has(key: string): boolean;
/**
* Delete a key from the cache
*/
delete(key: string): boolean;
/**
* Clear all entries
*/
clear(): void;
/**
* Get cache statistics
*/
getStats(): CacheStats;
/**
* Get all keys
*/
keys(): string[];
/**
* Get cache size
*/
size(): number;
/**
* Create a cache key from multiple parts
*/
static createKey(...parts: any[]): string;
/**
* Clean up expired entries
*/
private cleanup;
/**
* Evict least recently used entry
*/
private evictLRU;
/**
* Estimate size of a value in bytes
*/
private estimateSize;
/**
* Start automatic cleanup interval
*/
private startCleanupInterval;
/**
* Stop the cache manager and cleanup
*/
destroy(): void;
}
declare enum LogLevel {
ERROR = 0,
WARN = 1,
INFO = 2,
DEBUG = 3
}
interface LoggerOptions {
level: LogLevel;
prefix?: string;
timestamp?: boolean;
colors?: boolean;
}
interface LogEntry {
level: LogLevel;
message: string;
timestamp: Date;
prefix?: string;
data?: any;
error?: Error;
}
declare class Logger {
private options;
private handlers;
constructor(options?: Partial<LoggerOptions>);
/**
* Add a custom log handler
*/
addHandler(handler: (entry: LogEntry) => void): void;
/**
* Remove a log handler
*/
removeHandler(handler: (entry: LogEntry) => void): void;
/**
* Log an error message
*/
error(message: string, error?: Error | any): void;
/**
* Log a warning message
*/
warn(message: string, data?: any): void;
/**
* Log an info message
*/
info(message: string, data?: any): void;
/**
* Log a debug message
*/
debug(message: string, data?: any): void;
/**
* Core logging method
*/
private log;
/**
* Format and output to console
*/
private consoleOutput;
/**
* Colorize text based on log level
*/
private colorize;
/**
* Create a child logger with a prefix
*/
child(prefix: string): Logger;
/**
* Set the log level
*/
setLevel(level: LogLevel): void;
/**
* Get the current log level
*/
getLevel(): LogLevel;
}
declare const logger: Logger;
interface ErrorContext {
operation?: string;
file?: string;
user?: string;
metadata?: Record<string, any>;
}
declare class VibecodeError extends Error {
code: string;
statusCode: number;
context?: ErrorContext;
isOperational: boolean;
constructor(message: string, code?: string, statusCode?: number, isOperational?: boolean, context?: ErrorContext);
}
declare class ValidationError extends VibecodeError {
constructor(message: string, context?: ErrorContext);
}
declare class AuthorizationError extends VibecodeError {
constructor(message: string, context?: ErrorContext);
}
declare class NotFoundError extends VibecodeError {
constructor(message: string, context?: ErrorContext);
}
declare class RateLimitError extends VibecodeError {
retryAfter: number;
constructor(message: string, retryAfter: number, context?: ErrorContext);
}
declare class ErrorHandler {
private errorHandlers;
/**
* Register a custom error handler for specific error codes
*/
registerHandler(errorCode: string, handler: (error: VibecodeError) => void): void;
/**
* Handle an error
*/
handle(error: Error | VibecodeError, context?: ErrorContext): {
message: string;
code: string;
statusCode: number;
details?: any;
};
/**
* Convert any error to VibecodeError
*/
private toVibecodeError;
/**
* Log error with appropriate level
*/
private logError;
/**
* Create error response
*/
private createErrorResponse;
/**
* Wrap an async function with error handling
*/
wrapAsync<T extends (...args: any[]) => Promise<any>>(fn: T, context?: ErrorContext): T;
/**
* Create a middleware for Express-like frameworks
*/
middleware(): (err: Error, req: any, res: any, next: any) => void;
}
declare const errorHandler: ErrorHandler;
export { type APIResponse, AuthorizationError, type CacheEntry, CacheManager, type ErrorContext, ErrorHandler, type ErrorResponse, type FileInfo, FileScanner, type LogEntry, LogLevel, Logger, type LoggerOptions, MarkdownParser, NotFoundError, PathValidator, type PathValidatorOptions, RateLimitError, type RateLimitInfo, RateLimiter, type RateLimiterOptions, type ScanOptions, type ScanProgress, type ServerConfig, TaskExtractor, type TaskScanResult, ValidationError, VibecodeError, errorHandler, logger };