Refactor: Remove unused logging and path management utilities
- Removed the rollingLog import and its usage in doctor.ts. - Deleted the animatedRainbow function from install.ts. - Removed the log following implementation in logs.ts. - Deleted the PathResolver class and its related methods in paths.ts. - Removed the SettingsManager class and its associated methods in settings.ts. - Deleted the JSONLStorageProvider class and its methods in storage.ts. - Removed the CompressionError class from types.ts. - Cleaned up the Platform utility by removing unnecessary methods related to shell and file permissions.
This commit is contained in:
Vendored
+52
-52
File diff suppressed because one or more lines are too long
@@ -3,7 +3,6 @@ import fs from 'fs';
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { PathDiscovery } from '../services/path-discovery.js';
|
import { PathDiscovery } from '../services/path-discovery.js';
|
||||||
import { createStores } from '../services/sqlite/index.js';
|
import { createStores } from '../services/sqlite/index.js';
|
||||||
import { rollingLog } from '../shared/rolling-log.js';
|
|
||||||
|
|
||||||
type CheckStatus = 'pass' | 'fail' | 'warn';
|
type CheckStatus = 'pass' | 'fail' | 'warn';
|
||||||
|
|
||||||
@@ -93,8 +92,4 @@ export async function doctor(options: OptionValues = {}): Promise<void> {
|
|||||||
console.log('=================');
|
console.log('=================');
|
||||||
checks.forEach(printCheck);
|
checks.forEach(printCheck);
|
||||||
}
|
}
|
||||||
|
|
||||||
rollingLog('info', 'doctor run completed', {
|
|
||||||
status: checks.map((c) => c.status)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,28 +35,6 @@ function createLoadingAnimation(message: string) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create animated rainbow text with adjustable speed
|
|
||||||
function animatedRainbow(text: string, speed: number = 100): Promise<void> {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
let offset = 0;
|
|
||||||
const maxFrames = 10;
|
|
||||||
|
|
||||||
const interval = setInterval(() => {
|
|
||||||
// Create a shifted gradient by rotating through different presets
|
|
||||||
const gradients = [fastRainbow, vibrantRainbow, gradient.rainbow, gradient.pastel];
|
|
||||||
const shifted = gradients[offset % gradients.length](text);
|
|
||||||
process.stdout.write('\r' + shifted);
|
|
||||||
offset++;
|
|
||||||
|
|
||||||
if (offset >= maxFrames) {
|
|
||||||
clearInterval(interval);
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
}, speed);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Fast rainbow gradient preset with tighter color transitions
|
// Fast rainbow gradient preset with tighter color transitions
|
||||||
const fastRainbow = gradient(['#ff0000', '#ff4500', '#ffa500', '#ffff00', '#00ff00', '#00ffff', '#0000ff', '#8b00ff']);
|
const fastRainbow = gradient(['#ff0000', '#ff4500', '#ffa500', '#ffff00', '#00ff00', '#00ffff', '#0000ff', '#8b00ff']);
|
||||||
const vibrantRainbow = gradient(['#ff006e', '#fb5607', '#ffbe0b', '#8338ec', '#3a86ff']);
|
const vibrantRainbow = gradient(['#ff006e', '#fb5607', '#ffbe0b', '#8338ec', '#3a86ff']);
|
||||||
|
|||||||
@@ -70,15 +70,4 @@ export async function logs(options: OptionValues = {}): Promise<void> {
|
|||||||
console.log('❌ Could not read logs directory: ~/.claude-mem/logs/');
|
console.log('❌ Could not read logs directory: ~/.claude-mem/logs/');
|
||||||
console.log(' Run a compression first to generate logs');
|
console.log(' Run a compression first to generate logs');
|
||||||
}
|
}
|
||||||
|
|
||||||
// <Block> 2.5 ====================================
|
|
||||||
if (options.follow) {
|
|
||||||
console.log('Following logs... (Press Ctrl+C to stop)');
|
|
||||||
// Basic follow implementation - would need more sophisticated watching in real usage
|
|
||||||
setInterval(() => {
|
|
||||||
// This would need proper file watching implementation
|
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
// </Block> =======================================
|
|
||||||
// </Block> =======================================
|
|
||||||
}
|
}
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
import { sep, basename } from 'path';
|
|
||||||
import { PathDiscovery } from '../services/path-discovery.js';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PathResolver utility for managing claude-mem file system paths
|
|
||||||
* Now delegates to PathDiscovery service for centralized path management
|
|
||||||
*/
|
|
||||||
export class PathResolver {
|
|
||||||
private pathDiscovery: PathDiscovery;
|
|
||||||
|
|
||||||
// <Block> 1.1 ====================================
|
|
||||||
constructor() {
|
|
||||||
this.pathDiscovery = PathDiscovery.getInstance();
|
|
||||||
}
|
|
||||||
// </Block> =======================================
|
|
||||||
|
|
||||||
// <Block> 1.2 ====================================
|
|
||||||
getConfigDir(): string {
|
|
||||||
return this.pathDiscovery.getDataDirectory();
|
|
||||||
}
|
|
||||||
// </Block> =======================================
|
|
||||||
|
|
||||||
// <Block> 1.3 ====================================
|
|
||||||
getIndexDir(): string {
|
|
||||||
return this.pathDiscovery.getIndexDirectory();
|
|
||||||
}
|
|
||||||
// </Block> =======================================
|
|
||||||
|
|
||||||
// <Block> 1.4 ====================================
|
|
||||||
getIndexPath(): string {
|
|
||||||
return this.pathDiscovery.getIndexPath();
|
|
||||||
}
|
|
||||||
// </Block> =======================================
|
|
||||||
|
|
||||||
// <Block> 1.5 ====================================
|
|
||||||
getArchiveDir(): string {
|
|
||||||
return this.pathDiscovery.getArchivesDirectory();
|
|
||||||
}
|
|
||||||
// </Block> =======================================
|
|
||||||
|
|
||||||
// <Block> 1.6 ====================================
|
|
||||||
getProjectArchiveDir(projectName: string): string {
|
|
||||||
return this.pathDiscovery.getProjectArchiveDirectory(projectName);
|
|
||||||
}
|
|
||||||
// </Block> =======================================
|
|
||||||
|
|
||||||
// <Block> 1.7 ====================================
|
|
||||||
getLogsDir(): string {
|
|
||||||
return this.pathDiscovery.getLogsDirectory();
|
|
||||||
}
|
|
||||||
// </Block> =======================================
|
|
||||||
|
|
||||||
// <Block> 1.8 ====================================
|
|
||||||
static ensureDirectory(dirPath: string): void {
|
|
||||||
PathDiscovery.getInstance().ensureDirectory(dirPath);
|
|
||||||
}
|
|
||||||
// </Block> =======================================
|
|
||||||
|
|
||||||
// <Block> 1.9 ====================================
|
|
||||||
static ensureDirectories(dirPaths: string[]): void {
|
|
||||||
PathDiscovery.getInstance().ensureDirectories(dirPaths);
|
|
||||||
}
|
|
||||||
// </Block> =======================================
|
|
||||||
|
|
||||||
// <Block> 1.10 ===================================
|
|
||||||
static extractProjectName(transcriptPath: string): string {
|
|
||||||
return PathDiscovery.extractProjectName(transcriptPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
// <Block> 1.11 ===================================
|
|
||||||
/**
|
|
||||||
* DRY utility function: Canonical source for getting the current project prefix
|
|
||||||
* Replaces all instances of path.basename(process.cwd()) across the codebase
|
|
||||||
* @returns The current project directory name, sanitized for use as a prefix
|
|
||||||
*/
|
|
||||||
static getCurrentProjectPrefix(): string {
|
|
||||||
return PathDiscovery.getCurrentProjectName();
|
|
||||||
}
|
|
||||||
// </Block> =======================================
|
|
||||||
|
|
||||||
// <Block> 1.12 ===================================
|
|
||||||
/**
|
|
||||||
* DRY utility function: Gets raw project name without sanitization
|
|
||||||
* For use in contexts where original directory name is needed (e.g., display)
|
|
||||||
* @returns The current project directory name as-is
|
|
||||||
*/
|
|
||||||
static getCurrentProjectName(): string {
|
|
||||||
return PathDiscovery.getCurrentProjectName();
|
|
||||||
}
|
|
||||||
// </Block> =======================================
|
|
||||||
}
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
import { readFileSync, existsSync } from 'fs';
|
|
||||||
import { join } from 'path';
|
|
||||||
import { PathResolver } from './paths.js';
|
|
||||||
import type { Settings } from './types.js';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Settings utilities for managing ~/.claude-mem/settings.json
|
|
||||||
*/
|
|
||||||
export class SettingsManager {
|
|
||||||
private static settingsPath: string;
|
|
||||||
private static cachedSettings: Settings | null = null;
|
|
||||||
|
|
||||||
static {
|
|
||||||
const pathResolver = new PathResolver();
|
|
||||||
this.settingsPath = join(pathResolver.getConfigDir(), 'settings.json');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Safely read settings.json with error handling
|
|
||||||
* Returns empty object if file doesn't exist or is malformed
|
|
||||||
*/
|
|
||||||
static readSettings(): Settings {
|
|
||||||
// Return cached settings if available
|
|
||||||
if (this.cachedSettings !== null) {
|
|
||||||
return this.cachedSettings;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (existsSync(this.settingsPath)) {
|
|
||||||
const content = readFileSync(this.settingsPath, 'utf-8');
|
|
||||||
const settings = JSON.parse(content) as Settings;
|
|
||||||
this.cachedSettings = settings;
|
|
||||||
return settings;
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
// File is malformed or unreadable - return empty settings
|
|
||||||
}
|
|
||||||
|
|
||||||
// File doesn't exist or failed to read
|
|
||||||
const emptySettings: Settings = {};
|
|
||||||
this.cachedSettings = emptySettings;
|
|
||||||
return emptySettings;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a specific setting value with optional fallback
|
|
||||||
*/
|
|
||||||
static getSetting<K extends keyof Settings>(
|
|
||||||
key: K,
|
|
||||||
fallback?: Settings[K]
|
|
||||||
): Settings[K] | undefined {
|
|
||||||
const settings = this.readSettings();
|
|
||||||
return settings[key] ?? fallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the Claude binary path from settings
|
|
||||||
* Falls back to 'claude' if not found or settings don't exist
|
|
||||||
*/
|
|
||||||
static getClaudePath(): string {
|
|
||||||
const claudePath = this.getSetting('claudePath', 'claude');
|
|
||||||
return claudePath as string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clear cached settings (useful for testing or after settings changes)
|
|
||||||
*/
|
|
||||||
static clearCache(): void {
|
|
||||||
this.cachedSettings = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convenience function to get Claude binary path
|
|
||||||
* Can be imported directly for simple use cases
|
|
||||||
*/
|
|
||||||
export function getClaudePath(): string {
|
|
||||||
return SettingsManager.getClaudePath();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convenience function to read all settings
|
|
||||||
* Can be imported directly for simple use cases
|
|
||||||
*/
|
|
||||||
export function readSettings(): Settings {
|
|
||||||
return SettingsManager.readSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convenience function to get a specific setting
|
|
||||||
* Can be imported directly for simple use cases
|
|
||||||
*/
|
|
||||||
export function getSetting<K extends keyof Settings>(
|
|
||||||
key: K,
|
|
||||||
fallback?: Settings[K]
|
|
||||||
): Settings[K] | undefined {
|
|
||||||
return SettingsManager.getSetting(key, fallback);
|
|
||||||
}
|
|
||||||
+3
-217
@@ -1,5 +1,3 @@
|
|||||||
import fs from 'fs';
|
|
||||||
import { PathDiscovery } from '../services/path-discovery.js';
|
|
||||||
import {
|
import {
|
||||||
createStores,
|
createStores,
|
||||||
SessionStore,
|
SessionStore,
|
||||||
@@ -166,237 +164,25 @@ export class SQLiteStorageProvider implements IStorageProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* JSONL-based storage provider (legacy fallback)
|
|
||||||
*/
|
|
||||||
export class JSONLStorageProvider implements IStorageProvider {
|
|
||||||
public readonly backend = 'jsonl';
|
|
||||||
|
|
||||||
private pathDiscovery = PathDiscovery.getInstance();
|
|
||||||
|
|
||||||
async isAvailable(): Promise<boolean> {
|
|
||||||
try {
|
|
||||||
// Ensure data directory exists
|
|
||||||
const dataDir = this.pathDiscovery.getDataDirectory();
|
|
||||||
fs.mkdirSync(dataDir, { recursive: true });
|
|
||||||
return true;
|
|
||||||
} catch {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private appendToIndex(obj: any): void {
|
|
||||||
const indexPath = this.pathDiscovery.getIndexPath();
|
|
||||||
fs.appendFileSync(indexPath, JSON.stringify(obj) + '\\n', 'utf8');
|
|
||||||
}
|
|
||||||
|
|
||||||
async createSession(session: SessionInput): Promise<void> {
|
|
||||||
const sessionRecord = {
|
|
||||||
type: 'session',
|
|
||||||
session_id: session.session_id,
|
|
||||||
project: session.project,
|
|
||||||
timestamp: session.created_at
|
|
||||||
};
|
|
||||||
this.appendToIndex(sessionRecord);
|
|
||||||
}
|
|
||||||
|
|
||||||
async getSession(): Promise<null> {
|
|
||||||
// Not supported in JSONL mode
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
async hasSession(sessionId: string): Promise<boolean> {
|
|
||||||
const sessionIds = await this.getAllSessionIds();
|
|
||||||
return sessionIds.has(sessionId);
|
|
||||||
}
|
|
||||||
|
|
||||||
async getAllSessionIds(): Promise<Set<string>> {
|
|
||||||
const indexPath = this.pathDiscovery.getIndexPath();
|
|
||||||
if (!fs.existsSync(indexPath)) {
|
|
||||||
return new Set();
|
|
||||||
}
|
|
||||||
|
|
||||||
const content = fs.readFileSync(indexPath, 'utf-8');
|
|
||||||
const lines = content.trim().split('\\n').filter(line => line.trim());
|
|
||||||
const sessionIds = new Set<string>();
|
|
||||||
|
|
||||||
for (const line of lines) {
|
|
||||||
try {
|
|
||||||
const obj = JSON.parse(line);
|
|
||||||
if (obj.session_id) {
|
|
||||||
sessionIds.add(obj.session_id);
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
// Skip malformed JSON
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sessionIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
async getRecentSessions(): Promise<SessionRow[]> {
|
|
||||||
// Not fully supported in JSONL mode - return empty array
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
async getRecentSessionsForProject(): Promise<SessionRow[]> {
|
|
||||||
// Not fully supported in JSONL mode - return empty array
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
async createMemory(memory: MemoryInput): Promise<void> {
|
|
||||||
const memoryRecord = {
|
|
||||||
type: 'memory',
|
|
||||||
text: memory.text,
|
|
||||||
document_id: memory.document_id,
|
|
||||||
keywords: memory.keywords,
|
|
||||||
session_id: memory.session_id,
|
|
||||||
project: memory.project,
|
|
||||||
timestamp: memory.created_at,
|
|
||||||
archive: memory.archive_basename
|
|
||||||
};
|
|
||||||
this.appendToIndex(memoryRecord);
|
|
||||||
}
|
|
||||||
|
|
||||||
async createMemories(memories: MemoryInput[]): Promise<void> {
|
|
||||||
for (const memory of memories) {
|
|
||||||
await this.createMemory(memory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async getRecentMemories(): Promise<MemoryRow[]> {
|
|
||||||
// Not fully supported in JSONL mode - return empty array
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
async getRecentMemoriesForProject(): Promise<MemoryRow[]> {
|
|
||||||
// Not fully supported in JSONL mode - return empty array
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
async hasDocumentId(documentId: string): Promise<boolean> {
|
|
||||||
const indexPath = this.pathDiscovery.getIndexPath();
|
|
||||||
if (!fs.existsSync(indexPath)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const content = fs.readFileSync(indexPath, 'utf-8');
|
|
||||||
const lines = content.trim().split('\\n').filter(line => line.trim());
|
|
||||||
|
|
||||||
for (const line of lines) {
|
|
||||||
try {
|
|
||||||
const obj = JSON.parse(line);
|
|
||||||
if (obj.type === 'memory' && obj.document_id === documentId) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
// Skip malformed JSON
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
async createOverview(overview: OverviewInput): Promise<void> {
|
|
||||||
const overviewRecord = {
|
|
||||||
type: 'overview',
|
|
||||||
content: overview.content,
|
|
||||||
session_id: overview.session_id,
|
|
||||||
project: overview.project,
|
|
||||||
timestamp: overview.created_at
|
|
||||||
};
|
|
||||||
this.appendToIndex(overviewRecord);
|
|
||||||
}
|
|
||||||
|
|
||||||
async upsertOverview(overview: OverviewInput): Promise<void> {
|
|
||||||
// Just append in JSONL mode (no real upsert)
|
|
||||||
await this.createOverview(overview);
|
|
||||||
}
|
|
||||||
|
|
||||||
async getRecentOverviews(): Promise<OverviewRow[]> {
|
|
||||||
// Not fully supported in JSONL mode - return empty array
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
async getRecentOverviewsForProject(): Promise<OverviewRow[]> {
|
|
||||||
// Not fully supported in JSONL mode - return empty array
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
async createDiagnostic(diagnostic: DiagnosticInput): Promise<void> {
|
|
||||||
const diagnosticRecord = {
|
|
||||||
type: 'diagnostic',
|
|
||||||
message: diagnostic.message,
|
|
||||||
session_id: diagnostic.session_id,
|
|
||||||
project: diagnostic.project,
|
|
||||||
timestamp: diagnostic.created_at
|
|
||||||
};
|
|
||||||
this.appendToIndex(diagnosticRecord);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Storage provider factory and singleton
|
* Storage provider singleton
|
||||||
*/
|
*/
|
||||||
let storageProvider: IStorageProvider | null = null;
|
let storageProvider: IStorageProvider | null = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the configured storage provider
|
* Get the configured storage provider (always SQLite)
|
||||||
*/
|
*/
|
||||||
export async function getStorageProvider(): Promise<IStorageProvider> {
|
export async function getStorageProvider(): Promise<IStorageProvider> {
|
||||||
if (storageProvider) {
|
if (storageProvider) {
|
||||||
return storageProvider;
|
return storageProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try SQLite first
|
|
||||||
const sqliteProvider = new SQLiteStorageProvider();
|
const sqliteProvider = new SQLiteStorageProvider();
|
||||||
if (await sqliteProvider.isAvailable()) {
|
if (await sqliteProvider.isAvailable()) {
|
||||||
storageProvider = sqliteProvider;
|
storageProvider = sqliteProvider;
|
||||||
return storageProvider;
|
return storageProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fall back to JSONL
|
throw new Error('SQLite storage backend unavailable');
|
||||||
const jsonlProvider = new JSONLStorageProvider();
|
|
||||||
if (await jsonlProvider.isAvailable()) {
|
|
||||||
storageProvider = jsonlProvider;
|
|
||||||
return storageProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error('No storage backend available');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Force a specific storage provider (useful for testing)
|
|
||||||
*/
|
|
||||||
export function setStorageProvider(provider: IStorageProvider): void {
|
|
||||||
storageProvider = provider;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if SQLite migration is needed
|
|
||||||
*/
|
|
||||||
export async function needsMigration(): Promise<boolean> {
|
|
||||||
const pathDiscovery = PathDiscovery.getInstance();
|
|
||||||
const indexPath = pathDiscovery.getIndexPath();
|
|
||||||
|
|
||||||
// If JSONL exists but SQLite is not available, migration is needed
|
|
||||||
if (fs.existsSync(indexPath)) {
|
|
||||||
const sqliteProvider = new SQLiteStorageProvider();
|
|
||||||
const sqliteAvailable = await sqliteProvider.isAvailable();
|
|
||||||
|
|
||||||
if (!sqliteAvailable) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if SQLite has data
|
|
||||||
try {
|
|
||||||
const stores = await createStores();
|
|
||||||
const sessionCount = stores.sessions.count();
|
|
||||||
return sessionCount === 0; // Needs migration if SQLite is empty
|
|
||||||
} catch {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
@@ -5,24 +5,6 @@
|
|||||||
* Only includes types that are actively imported and used.
|
* Only includes types that are actively imported and used.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// =============================================================================
|
|
||||||
// ERROR CLASSES
|
|
||||||
// =============================================================================
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Custom error class for compression failures
|
|
||||||
*/
|
|
||||||
export class CompressionError extends Error {
|
|
||||||
constructor(
|
|
||||||
message: string,
|
|
||||||
public transcriptPath: string,
|
|
||||||
public stage: 'reading' | 'analyzing' | 'compressing' | 'writing'
|
|
||||||
) {
|
|
||||||
super(message);
|
|
||||||
this.name = 'CompressionError';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// CONFIGURATION TYPES
|
// CONFIGURATION TYPES
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|||||||
+1
-36
@@ -1,6 +1,5 @@
|
|||||||
import { platform, homedir } from 'os';
|
import { platform, homedir } from 'os';
|
||||||
import { execSync } from 'child_process';
|
import { execSync } from 'child_process';
|
||||||
import { chmodSync } from 'fs';
|
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
||||||
const isWindows = platform() === 'win32';
|
const isWindows = platform() === 'win32';
|
||||||
@@ -10,20 +9,6 @@ const isWindows = platform() === 'win32';
|
|||||||
* Handles differences between Windows and Unix-like systems
|
* Handles differences between Windows and Unix-like systems
|
||||||
*/
|
*/
|
||||||
export const Platform = {
|
export const Platform = {
|
||||||
/**
|
|
||||||
* Returns the appropriate shell for the current platform
|
|
||||||
*/
|
|
||||||
getShell: (): string => {
|
|
||||||
return isWindows ? 'powershell' : '/bin/sh';
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the file extension for hook scripts
|
|
||||||
*/
|
|
||||||
getHookExtension: (): string => {
|
|
||||||
return '.js'; // Both platforms can execute Node.js scripts
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the path to an executable command
|
* Finds the path to an executable command
|
||||||
* @param name - Name of the executable to find
|
* @param name - Name of the executable to find
|
||||||
@@ -37,16 +22,6 @@ export const Platform = {
|
|||||||
}).trim();
|
}).trim();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Makes a file executable (Unix only - no-op on Windows)
|
|
||||||
* @param path - Path to the file to make executable
|
|
||||||
*/
|
|
||||||
makeExecutable: (path: string): void => {
|
|
||||||
if (!isWindows) {
|
|
||||||
chmodSync(path, 0o755);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Installs uv package manager using platform-specific method
|
* Installs uv package manager using platform-specific method
|
||||||
*/
|
*/
|
||||||
@@ -98,15 +73,5 @@ export const Platform = {
|
|||||||
|
|
||||||
// Bash/Zsh alias syntax
|
// Bash/Zsh alias syntax
|
||||||
return `alias ${aliasName}='${command}'`;
|
return `alias ${aliasName}='${command}'`;
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether the current platform is Windows
|
|
||||||
*/
|
|
||||||
isWindows: (): boolean => isWindows,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether the current platform is Unix-like (macOS/Linux)
|
|
||||||
*/
|
|
||||||
isUnix: (): boolean => !isWindows
|
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user