@sylphx/flow 1.8.0 → 1.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +72 -0
- package/assets/output-styles/silent.md +145 -8
- package/assets/rules/core.md +19 -2
- package/package.json +2 -12
- package/src/commands/flow/execute.ts +470 -0
- package/src/commands/flow/index.ts +11 -0
- package/src/commands/flow/prompt.ts +35 -0
- package/src/commands/flow/setup.ts +312 -0
- package/src/commands/flow/targets.ts +18 -0
- package/src/commands/flow/types.ts +47 -0
- package/src/commands/flow-command.ts +18 -967
- package/src/commands/flow-orchestrator.ts +14 -5
- package/src/commands/hook-command.ts +1 -1
- package/src/commands/init-core.ts +12 -3
- package/src/commands/run-command.ts +1 -1
- package/src/config/rules.ts +1 -1
- package/src/core/error-handling.ts +1 -1
- package/src/core/loop-controller.ts +1 -1
- package/src/core/state-detector.ts +1 -1
- package/src/core/target-manager.ts +1 -1
- package/src/index.ts +1 -1
- package/src/shared/files/index.ts +1 -1
- package/src/shared/processing/index.ts +1 -1
- package/src/targets/claude-code.ts +3 -3
- package/src/targets/opencode.ts +3 -3
- package/src/utils/agent-enhancer.ts +2 -2
- package/src/utils/{mcp-config.ts → config/mcp-config.ts} +4 -4
- package/src/utils/{paths.ts → config/paths.ts} +1 -1
- package/src/utils/{settings.ts → config/settings.ts} +1 -1
- package/src/utils/{target-config.ts → config/target-config.ts} +5 -5
- package/src/utils/{target-utils.ts → config/target-utils.ts} +3 -3
- package/src/utils/display/banner.ts +25 -0
- package/src/utils/display/status.ts +55 -0
- package/src/utils/{file-operations.ts → files/file-operations.ts} +2 -2
- package/src/utils/files/jsonc.ts +36 -0
- package/src/utils/{sync-utils.ts → files/sync-utils.ts} +3 -3
- package/src/utils/index.ts +42 -61
- package/src/utils/version.ts +47 -0
- package/src/components/benchmark-monitor.tsx +0 -331
- package/src/components/reindex-progress.tsx +0 -261
- package/src/composables/functional/index.ts +0 -14
- package/src/composables/functional/useEnvironment.ts +0 -171
- package/src/composables/functional/useFileSystem.ts +0 -139
- package/src/composables/index.ts +0 -4
- package/src/composables/useEnv.ts +0 -13
- package/src/composables/useRuntimeConfig.ts +0 -27
- package/src/core/ai-sdk.ts +0 -603
- package/src/core/app-factory.ts +0 -381
- package/src/core/builtin-agents.ts +0 -9
- package/src/core/command-system.ts +0 -550
- package/src/core/config-system.ts +0 -550
- package/src/core/connection-pool.ts +0 -390
- package/src/core/di-container.ts +0 -155
- package/src/core/headless-display.ts +0 -96
- package/src/core/interfaces/index.ts +0 -22
- package/src/core/interfaces/repository.interface.ts +0 -91
- package/src/core/interfaces/service.interface.ts +0 -133
- package/src/core/interfaces.ts +0 -96
- package/src/core/result.ts +0 -351
- package/src/core/service-config.ts +0 -252
- package/src/core/session-service.ts +0 -121
- package/src/core/storage-factory.ts +0 -115
- package/src/core/stream-handler.ts +0 -288
- package/src/core/type-utils.ts +0 -427
- package/src/core/unified-storage.ts +0 -456
- package/src/core/validation/limit.ts +0 -46
- package/src/core/validation/query.ts +0 -20
- package/src/db/auto-migrate.ts +0 -322
- package/src/db/base-database-client.ts +0 -144
- package/src/db/cache-db.ts +0 -218
- package/src/db/cache-schema.ts +0 -75
- package/src/db/database.ts +0 -70
- package/src/db/index.ts +0 -252
- package/src/db/memory-db.ts +0 -153
- package/src/db/memory-schema.ts +0 -29
- package/src/db/schema.ts +0 -289
- package/src/db/session-repository.ts +0 -733
- package/src/domains/index.ts +0 -6
- package/src/domains/utilities/index.ts +0 -6
- package/src/domains/utilities/time/index.ts +0 -5
- package/src/domains/utilities/time/tools.ts +0 -291
- package/src/services/agent-service.ts +0 -273
- package/src/services/evaluation-service.ts +0 -271
- package/src/services/functional/evaluation-logic.ts +0 -296
- package/src/services/functional/file-processor.ts +0 -273
- package/src/services/functional/index.ts +0 -12
- package/src/services/memory.service.ts +0 -476
- package/src/types/api/batch.ts +0 -108
- package/src/types/api/errors.ts +0 -118
- package/src/types/api/index.ts +0 -55
- package/src/types/api/requests.ts +0 -76
- package/src/types/api/responses.ts +0 -180
- package/src/types/api/websockets.ts +0 -85
- package/src/types/benchmark.ts +0 -49
- package/src/types/database.types.ts +0 -510
- package/src/types/memory-types.ts +0 -63
- package/src/utils/advanced-tokenizer.ts +0 -191
- package/src/utils/ai-model-fetcher.ts +0 -19
- package/src/utils/async-file-operations.ts +0 -516
- package/src/utils/audio-player.ts +0 -345
- package/src/utils/codebase-helpers.ts +0 -211
- package/src/utils/console-ui.ts +0 -79
- package/src/utils/database-errors.ts +0 -140
- package/src/utils/debug-logger.ts +0 -49
- package/src/utils/file-scanner.ts +0 -259
- package/src/utils/help.ts +0 -20
- package/src/utils/immutable-cache.ts +0 -106
- package/src/utils/jsonc.ts +0 -158
- package/src/utils/memory-tui.ts +0 -414
- package/src/utils/models-dev.ts +0 -91
- package/src/utils/parallel-operations.ts +0 -487
- package/src/utils/process-manager.ts +0 -155
- package/src/utils/prompts.ts +0 -120
- package/src/utils/search-tool-builder.ts +0 -214
- package/src/utils/session-manager.ts +0 -168
- package/src/utils/session-title.ts +0 -87
- package/src/utils/simplified-errors.ts +0 -410
- package/src/utils/template-engine.ts +0 -94
- package/src/utils/test-audio.ts +0 -71
- package/src/utils/todo-context.ts +0 -46
- package/src/utils/token-counter.ts +0 -288
- /package/src/utils/{cli-output.ts → display/cli-output.ts} +0 -0
- /package/src/utils/{logger.ts → display/logger.ts} +0 -0
- /package/src/utils/{notifications.ts → display/notifications.ts} +0 -0
- /package/src/utils/{secret-utils.ts → security/secret-utils.ts} +0 -0
- /package/src/utils/{security.ts → security/security.ts} +0 -0
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Database Error Handling - Simplified System
|
|
3
|
-
* Replaces complex error hierarchy with simplified database-specific errors
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
AppError,
|
|
8
|
-
createDatabaseError,
|
|
9
|
-
createValidationError,
|
|
10
|
-
ErrorCategory,
|
|
11
|
-
ErrorHandler,
|
|
12
|
-
ErrorSeverity,
|
|
13
|
-
DatabaseError as SimplifiedDatabaseError,
|
|
14
|
-
ValidationError as SimplifiedValidationError,
|
|
15
|
-
} from './simplified-errors.js';
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Simplified Database Error with additional database context
|
|
19
|
-
*/
|
|
20
|
-
export class DatabaseError extends SimplifiedDatabaseError {
|
|
21
|
-
constructor(
|
|
22
|
-
message: string,
|
|
23
|
-
operation?: string,
|
|
24
|
-
cause?: Error,
|
|
25
|
-
context?: Record<string, unknown>
|
|
26
|
-
) {
|
|
27
|
-
super(message, operation, context?.query as string);
|
|
28
|
-
this.cause = cause;
|
|
29
|
-
if (context) {
|
|
30
|
-
this.context = { ...this.context, ...context };
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Database-specific validation error
|
|
37
|
-
*/
|
|
38
|
-
export class ValidationError extends SimplifiedValidationError {
|
|
39
|
-
constructor(message: string, field: string, value?: unknown, cause?: Error) {
|
|
40
|
-
super(message, field, value);
|
|
41
|
-
this.cause = cause;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Database connection error
|
|
47
|
-
*/
|
|
48
|
-
export class ConnectionError extends AppError {
|
|
49
|
-
constructor(message: string, connectionDetails?: Record<string, unknown>, cause?: Error) {
|
|
50
|
-
super(
|
|
51
|
-
message,
|
|
52
|
-
'CONNECTION_ERROR',
|
|
53
|
-
ErrorCategory.NETWORK,
|
|
54
|
-
ErrorSeverity.HIGH,
|
|
55
|
-
connectionDetails,
|
|
56
|
-
cause
|
|
57
|
-
);
|
|
58
|
-
this.name = 'ConnectionError';
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Database migration error
|
|
64
|
-
*/
|
|
65
|
-
export class MigrationError extends AppError {
|
|
66
|
-
public readonly migrationName?: string;
|
|
67
|
-
|
|
68
|
-
constructor(message: string, migrationName?: string, cause?: Error) {
|
|
69
|
-
super(
|
|
70
|
-
message,
|
|
71
|
-
'MIGRATION_ERROR',
|
|
72
|
-
ErrorCategory.DATABASE,
|
|
73
|
-
ErrorSeverity.HIGH,
|
|
74
|
-
{ migrationName },
|
|
75
|
-
cause
|
|
76
|
-
);
|
|
77
|
-
this.migrationName = migrationName;
|
|
78
|
-
this.name = 'MigrationError';
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Execute database operation with comprehensive error handling
|
|
84
|
-
*/
|
|
85
|
-
export async function executeOperation<T>(
|
|
86
|
-
operation: string,
|
|
87
|
-
fn: () => Promise<T>,
|
|
88
|
-
context?: Record<string, unknown>
|
|
89
|
-
): Promise<T> {
|
|
90
|
-
const result = await ErrorHandler.execute(fn, { operation, ...context });
|
|
91
|
-
|
|
92
|
-
if (result.success) {
|
|
93
|
-
return result.data;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Convert to appropriate database error type
|
|
97
|
-
if (result.error instanceof AppError) {
|
|
98
|
-
throw result.error;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Unknown error - wrap in DatabaseError
|
|
102
|
-
throw createDatabaseError(result.error.message, operation, context?.query as string);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Type guard functions for database errors
|
|
107
|
-
*/
|
|
108
|
-
export function isDatabaseError(error: unknown): error is DatabaseError {
|
|
109
|
-
return error instanceof DatabaseError;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
export function isValidationError(error: unknown): error is ValidationError {
|
|
113
|
-
return error instanceof ValidationError;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
export function isConnectionError(error: unknown): error is ConnectionError {
|
|
117
|
-
return error instanceof ConnectionError;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
export function isMigrationError(error: unknown): error is MigrationError {
|
|
121
|
-
return error instanceof MigrationError;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Convenience functions for creating database errors
|
|
126
|
-
*/
|
|
127
|
-
export const createMigrationError = (
|
|
128
|
-
message: string,
|
|
129
|
-
migrationName?: string,
|
|
130
|
-
cause?: Error
|
|
131
|
-
): MigrationError => new MigrationError(message, migrationName, cause);
|
|
132
|
-
|
|
133
|
-
export const createConnectionError = (
|
|
134
|
-
message: string,
|
|
135
|
-
connectionDetails?: Record<string, unknown>,
|
|
136
|
-
cause?: Error
|
|
137
|
-
): ConnectionError => new ConnectionError(message, connectionDetails, cause);
|
|
138
|
-
|
|
139
|
-
// Re-export for backward compatibility
|
|
140
|
-
export { createDatabaseError, createValidationError, ErrorHandler, AppError };
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Debug Logger
|
|
3
|
-
* Uses industry-standard 'debug' package
|
|
4
|
-
*
|
|
5
|
-
* Usage:
|
|
6
|
-
* DEBUG=* bun ./packages/flow/src/index.ts // All debug logs
|
|
7
|
-
* DEBUG=sylphx:* bun ... // All sylphx namespaces
|
|
8
|
-
* DEBUG=sylphx:search:* bun ... // Search namespace
|
|
9
|
-
* (no DEBUG) bun ... // No debug logs
|
|
10
|
-
*
|
|
11
|
-
* Examples:
|
|
12
|
-
* import { createLogger } from '../utils/debug-logger.js';
|
|
13
|
-
*
|
|
14
|
-
* const log = createLogger('search:indexing');
|
|
15
|
-
* log('Indexing started:', filePath);
|
|
16
|
-
*
|
|
17
|
-
* Features from 'debug' package:
|
|
18
|
-
* - Color-coded namespaces
|
|
19
|
-
* - Timestamp support (DEBUG_COLORS=no for no color)
|
|
20
|
-
* - Wildcard matching (DEBUG=sylphx:*)
|
|
21
|
-
* - Conditional logging (no performance impact when disabled)
|
|
22
|
-
* - Industry standard (used by Express, Socket.io, etc.)
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
import debug from 'debug';
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Create a logger for a specific namespace
|
|
29
|
-
* Namespace will be prefixed with 'sylphx:'
|
|
30
|
-
*
|
|
31
|
-
* @example
|
|
32
|
-
* const log = createLogger('search:indexing');
|
|
33
|
-
* log('Indexing started:', filePath);
|
|
34
|
-
*
|
|
35
|
-
* // Enable with:
|
|
36
|
-
* // DEBUG=sylphx:search:indexing bun ./packages/flow/src/index.ts
|
|
37
|
-
*/
|
|
38
|
-
export function createLogger(namespace: string) {
|
|
39
|
-
return debug(`sylphx:${namespace}`);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* For backwards compatibility
|
|
44
|
-
* @deprecated Use createLogger instead
|
|
45
|
-
*/
|
|
46
|
-
export function debugLog(namespace: string, ...args: any[]) {
|
|
47
|
-
const log = debug(`sylphx:${namespace}`);
|
|
48
|
-
log(...args);
|
|
49
|
-
}
|
|
@@ -1,259 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* File Scanner
|
|
3
|
-
* Scan project files for @file auto-completion with caching
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { readdir, stat, readFile as fsReadFile, writeFile } from 'node:fs/promises';
|
|
7
|
-
import { join, relative } from 'node:path';
|
|
8
|
-
import { readFile } from 'node:fs/promises';
|
|
9
|
-
import { homedir } from 'node:os';
|
|
10
|
-
|
|
11
|
-
export interface FileInfo {
|
|
12
|
-
path: string;
|
|
13
|
-
relativePath: string;
|
|
14
|
-
size: number;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// Default ignore patterns
|
|
18
|
-
const DEFAULT_IGNORE = [
|
|
19
|
-
'node_modules',
|
|
20
|
-
'.git',
|
|
21
|
-
'dist',
|
|
22
|
-
'build',
|
|
23
|
-
'.next',
|
|
24
|
-
'.vercel',
|
|
25
|
-
'.turbo',
|
|
26
|
-
'coverage',
|
|
27
|
-
'.cache',
|
|
28
|
-
'.sylphx',
|
|
29
|
-
'bun.lock',
|
|
30
|
-
'package-lock.json',
|
|
31
|
-
'yarn.lock',
|
|
32
|
-
];
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Load .gitignore patterns
|
|
36
|
-
*/
|
|
37
|
-
async function loadGitignore(rootPath: string): Promise<Set<string>> {
|
|
38
|
-
const patterns = new Set<string>(DEFAULT_IGNORE);
|
|
39
|
-
|
|
40
|
-
try {
|
|
41
|
-
const gitignorePath = join(rootPath, '.gitignore');
|
|
42
|
-
const content = await readFile(gitignorePath, 'utf8');
|
|
43
|
-
|
|
44
|
-
// Parse gitignore file
|
|
45
|
-
for (const line of content.split('\n')) {
|
|
46
|
-
const trimmed = line.trim();
|
|
47
|
-
// Skip empty lines and comments
|
|
48
|
-
if (trimmed && !trimmed.startsWith('#')) {
|
|
49
|
-
// Remove trailing slashes
|
|
50
|
-
const pattern = trimmed.endsWith('/') ? trimmed.slice(0, -1) : trimmed;
|
|
51
|
-
patterns.add(pattern);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
} catch {
|
|
55
|
-
// No .gitignore file, use defaults only
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return patterns;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Check if path should be ignored
|
|
63
|
-
*/
|
|
64
|
-
function shouldIgnore(relativePath: string, patterns: Set<string>): boolean {
|
|
65
|
-
// Check if any part of the path matches ignore patterns
|
|
66
|
-
const parts = relativePath.split('/');
|
|
67
|
-
|
|
68
|
-
for (const pattern of patterns) {
|
|
69
|
-
// Exact match
|
|
70
|
-
if (relativePath === pattern) return true;
|
|
71
|
-
|
|
72
|
-
// Directory match
|
|
73
|
-
if (parts.includes(pattern)) return true;
|
|
74
|
-
|
|
75
|
-
// Glob pattern (basic support for *)
|
|
76
|
-
if (pattern.includes('*')) {
|
|
77
|
-
const regex = new RegExp('^' + pattern.replace(/\*/g, '.*') + '$');
|
|
78
|
-
if (regex.test(relativePath)) return true;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return false;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Recursively scan directory for files (parallelized)
|
|
87
|
-
*/
|
|
88
|
-
async function scanDirectory(
|
|
89
|
-
dirPath: string,
|
|
90
|
-
rootPath: string,
|
|
91
|
-
patterns: Set<string>,
|
|
92
|
-
results: FileInfo[] = []
|
|
93
|
-
): Promise<FileInfo[]> {
|
|
94
|
-
try {
|
|
95
|
-
const entries = await readdir(dirPath, { withFileTypes: true });
|
|
96
|
-
|
|
97
|
-
// Separate files and directories for parallel processing
|
|
98
|
-
const files: typeof entries = [];
|
|
99
|
-
const directories: typeof entries = [];
|
|
100
|
-
|
|
101
|
-
for (const entry of entries) {
|
|
102
|
-
const fullPath = join(dirPath, entry.name);
|
|
103
|
-
const relativePath = relative(rootPath, fullPath);
|
|
104
|
-
|
|
105
|
-
// Skip ignored paths
|
|
106
|
-
if (shouldIgnore(relativePath, patterns)) {
|
|
107
|
-
continue;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
if (entry.isDirectory()) {
|
|
111
|
-
directories.push(entry);
|
|
112
|
-
} else if (entry.isFile()) {
|
|
113
|
-
files.push(entry);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// Process files in parallel (no need to stat each one individually)
|
|
118
|
-
// Use entry.isFile() which we already know, skip stat() call for performance
|
|
119
|
-
const fileResults = files.map((entry) => {
|
|
120
|
-
const fullPath = join(dirPath, entry.name);
|
|
121
|
-
const relativePath = relative(rootPath, fullPath);
|
|
122
|
-
return {
|
|
123
|
-
path: fullPath,
|
|
124
|
-
relativePath,
|
|
125
|
-
size: 0, // We skip stat() for performance, size not critical for autocomplete
|
|
126
|
-
};
|
|
127
|
-
});
|
|
128
|
-
results.push(...fileResults);
|
|
129
|
-
|
|
130
|
-
// Process subdirectories in parallel
|
|
131
|
-
if (directories.length > 0) {
|
|
132
|
-
const subdirResults = await Promise.all(
|
|
133
|
-
directories.map((entry) => {
|
|
134
|
-
const fullPath = join(dirPath, entry.name);
|
|
135
|
-
return scanDirectory(fullPath, rootPath, patterns, []);
|
|
136
|
-
})
|
|
137
|
-
);
|
|
138
|
-
|
|
139
|
-
// Flatten results from all subdirectories
|
|
140
|
-
for (const subdirResult of subdirResults) {
|
|
141
|
-
results.push(...subdirResult);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
} catch (error) {
|
|
145
|
-
// Skip directories we can't read
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
return results;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// Cache for scanned files
|
|
152
|
-
const CACHE_DIR = join(homedir(), '.sylphx', 'cache');
|
|
153
|
-
const CACHE_VERSION = 1;
|
|
154
|
-
|
|
155
|
-
interface ScanCache {
|
|
156
|
-
version: number;
|
|
157
|
-
rootPath: string;
|
|
158
|
-
timestamp: number;
|
|
159
|
-
files: FileInfo[];
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Get cache file path for a project
|
|
164
|
-
*/
|
|
165
|
-
function getCachePath(rootPath: string): string {
|
|
166
|
-
// Use hash of root path as cache filename
|
|
167
|
-
const hash = Buffer.from(rootPath).toString('base64').replace(/[/+=]/g, '_');
|
|
168
|
-
return join(CACHE_DIR, `filescan-${hash}.json`);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Load cached file list if valid
|
|
173
|
-
*/
|
|
174
|
-
async function loadCache(rootPath: string): Promise<FileInfo[] | null> {
|
|
175
|
-
try {
|
|
176
|
-
const cachePath = getCachePath(rootPath);
|
|
177
|
-
const content = await fsReadFile(cachePath, 'utf8');
|
|
178
|
-
const cache: ScanCache = JSON.parse(content);
|
|
179
|
-
|
|
180
|
-
// Validate cache
|
|
181
|
-
if (cache.version !== CACHE_VERSION || cache.rootPath !== rootPath) {
|
|
182
|
-
return null;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// Check if cache is still fresh (less than 5 minutes old)
|
|
186
|
-
const age = Date.now() - cache.timestamp;
|
|
187
|
-
const MAX_CACHE_AGE = 5 * 60 * 1000; // 5 minutes
|
|
188
|
-
if (age > MAX_CACHE_AGE) {
|
|
189
|
-
return null;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
return cache.files;
|
|
193
|
-
} catch {
|
|
194
|
-
return null;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Save file list to cache
|
|
200
|
-
*/
|
|
201
|
-
async function saveCache(rootPath: string, files: FileInfo[]): Promise<void> {
|
|
202
|
-
try {
|
|
203
|
-
const cachePath = getCachePath(rootPath);
|
|
204
|
-
const cache: ScanCache = {
|
|
205
|
-
version: CACHE_VERSION,
|
|
206
|
-
rootPath,
|
|
207
|
-
timestamp: Date.now(),
|
|
208
|
-
files,
|
|
209
|
-
};
|
|
210
|
-
|
|
211
|
-
// Ensure cache directory exists
|
|
212
|
-
const { mkdir } = await import('node:fs/promises');
|
|
213
|
-
await mkdir(CACHE_DIR, { recursive: true });
|
|
214
|
-
|
|
215
|
-
// Write cache file
|
|
216
|
-
await writeFile(cachePath, JSON.stringify(cache), 'utf8');
|
|
217
|
-
} catch (error) {
|
|
218
|
-
// Ignore cache write errors
|
|
219
|
-
console.warn('Failed to write file scanner cache:', error);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
/**
|
|
224
|
-
* Scan project files with caching
|
|
225
|
-
* Returns list of files respecting .gitignore
|
|
226
|
-
*/
|
|
227
|
-
export async function scanProjectFiles(rootPath: string): Promise<FileInfo[]> {
|
|
228
|
-
// Try to load from cache first
|
|
229
|
-
const cached = await loadCache(rootPath);
|
|
230
|
-
if (cached) {
|
|
231
|
-
return cached;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
// Cache miss or stale, scan filesystem
|
|
235
|
-
const patterns = await loadGitignore(rootPath);
|
|
236
|
-
const files = await scanDirectory(rootPath, rootPath, patterns);
|
|
237
|
-
|
|
238
|
-
// Sort by path for consistent ordering
|
|
239
|
-
files.sort((a, b) => a.relativePath.localeCompare(b.relativePath));
|
|
240
|
-
|
|
241
|
-
// Save to cache for next time
|
|
242
|
-
saveCache(rootPath, files).catch(() => {
|
|
243
|
-
// Ignore cache save errors
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
return files;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* Filter files by query string
|
|
251
|
-
*/
|
|
252
|
-
export function filterFiles(files: FileInfo[], query: string): FileInfo[] {
|
|
253
|
-
if (!query) return files;
|
|
254
|
-
|
|
255
|
-
const lowerQuery = query.toLowerCase();
|
|
256
|
-
return files.filter((file) =>
|
|
257
|
-
file.relativePath.toLowerCase().includes(lowerQuery)
|
|
258
|
-
);
|
|
259
|
-
}
|
package/src/utils/help.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
export function showDefaultHelp(): void {
|
|
2
|
-
console.log('🚀 Sylphx Flow CLI - Legacy project initialization and flow management');
|
|
3
|
-
console.log('=========================================');
|
|
4
|
-
console.log('');
|
|
5
|
-
console.log('Available commands:');
|
|
6
|
-
console.log(' init Initialize project with Sylphx Flow');
|
|
7
|
-
console.log(' run Run workflows and flows');
|
|
8
|
-
console.log(' codebase Search and analyze codebase');
|
|
9
|
-
console.log(' knowledge Manage knowledge base');
|
|
10
|
-
console.log(' hook Load dynamic content for hooks');
|
|
11
|
-
console.log('');
|
|
12
|
-
console.log('Examples:');
|
|
13
|
-
console.log(' sylphx-flow init');
|
|
14
|
-
console.log(' sylphx-flow init --target claude-code');
|
|
15
|
-
console.log(' sylphx-flow run "your prompt"');
|
|
16
|
-
console.log(' sylphx-flow codebase search "function"');
|
|
17
|
-
console.log(' sylphx-flow knowledge search "React patterns"');
|
|
18
|
-
console.log('');
|
|
19
|
-
console.log('Run "sylphx-flow <command> --help" for more information about a command.');
|
|
20
|
-
}
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Immutable Cache
|
|
3
|
-
* Functional cache abstraction that returns new state on mutations
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export interface CacheState<K, V> {
|
|
7
|
-
readonly entries: ReadonlyMap<K, V>;
|
|
8
|
-
readonly size: number;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Create an empty cache state
|
|
13
|
-
*/
|
|
14
|
-
export const createCache = <K, V>(): CacheState<K, V> => ({
|
|
15
|
-
entries: new Map(),
|
|
16
|
-
size: 0,
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Set a value in the cache, returning new cache state
|
|
21
|
-
*/
|
|
22
|
-
export const cacheSet = <K, V>(cache: CacheState<K, V>, key: K, value: V): CacheState<K, V> => {
|
|
23
|
-
const newEntries = new Map(cache.entries);
|
|
24
|
-
newEntries.set(key, value);
|
|
25
|
-
return {
|
|
26
|
-
entries: newEntries,
|
|
27
|
-
size: newEntries.size,
|
|
28
|
-
};
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Get a value from the cache
|
|
33
|
-
*/
|
|
34
|
-
export const cacheGet = <K, V>(cache: CacheState<K, V>, key: K): V | undefined => {
|
|
35
|
-
return cache.entries.get(key);
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Delete a key from the cache, returning new cache state
|
|
40
|
-
*/
|
|
41
|
-
export const cacheDelete = <K, V>(cache: CacheState<K, V>, key: K): CacheState<K, V> => {
|
|
42
|
-
const newEntries = new Map(cache.entries);
|
|
43
|
-
newEntries.delete(key);
|
|
44
|
-
return {
|
|
45
|
-
entries: newEntries,
|
|
46
|
-
size: newEntries.size,
|
|
47
|
-
};
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Delete multiple keys matching a predicate, returning new cache state
|
|
52
|
-
*/
|
|
53
|
-
export const cacheDeleteWhere = <K, V>(
|
|
54
|
-
cache: CacheState<K, V>,
|
|
55
|
-
predicate: (key: K, value: V) => boolean
|
|
56
|
-
): CacheState<K, V> => {
|
|
57
|
-
const newEntries = new Map<K, V>();
|
|
58
|
-
for (const [key, value] of cache.entries) {
|
|
59
|
-
if (!predicate(key, value)) {
|
|
60
|
-
newEntries.set(key, value);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
return {
|
|
64
|
-
entries: newEntries,
|
|
65
|
-
size: newEntries.size,
|
|
66
|
-
};
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Clear all entries from the cache, returning new cache state
|
|
71
|
-
*/
|
|
72
|
-
export const cacheClear = <K, V>(): CacheState<K, V> => createCache();
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Get all keys from the cache
|
|
76
|
-
*/
|
|
77
|
-
export const cacheKeys = <K, V>(cache: CacheState<K, V>): K[] => {
|
|
78
|
-
return Array.from(cache.entries.keys());
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Enforce maximum cache size by removing oldest entries (FIFO)
|
|
83
|
-
* Returns new cache state
|
|
84
|
-
*/
|
|
85
|
-
export const cacheEnforceLimit = <K, V>(
|
|
86
|
-
cache: CacheState<K, V>,
|
|
87
|
-
maxSize: number
|
|
88
|
-
): CacheState<K, V> => {
|
|
89
|
-
if (cache.size <= maxSize) {
|
|
90
|
-
return cache;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const entriesToRemove = cache.size - maxSize;
|
|
94
|
-
const keys = Array.from(cache.entries.keys());
|
|
95
|
-
const keysToRemove = keys.slice(0, entriesToRemove);
|
|
96
|
-
|
|
97
|
-
const newEntries = new Map(cache.entries);
|
|
98
|
-
for (const key of keysToRemove) {
|
|
99
|
-
newEntries.delete(key);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
return {
|
|
103
|
-
entries: newEntries,
|
|
104
|
-
size: newEntries.size,
|
|
105
|
-
};
|
|
106
|
-
};
|