@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.
Files changed (126) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/assets/output-styles/silent.md +145 -8
  3. package/assets/rules/core.md +19 -2
  4. package/package.json +2 -12
  5. package/src/commands/flow/execute.ts +470 -0
  6. package/src/commands/flow/index.ts +11 -0
  7. package/src/commands/flow/prompt.ts +35 -0
  8. package/src/commands/flow/setup.ts +312 -0
  9. package/src/commands/flow/targets.ts +18 -0
  10. package/src/commands/flow/types.ts +47 -0
  11. package/src/commands/flow-command.ts +18 -967
  12. package/src/commands/flow-orchestrator.ts +14 -5
  13. package/src/commands/hook-command.ts +1 -1
  14. package/src/commands/init-core.ts +12 -3
  15. package/src/commands/run-command.ts +1 -1
  16. package/src/config/rules.ts +1 -1
  17. package/src/core/error-handling.ts +1 -1
  18. package/src/core/loop-controller.ts +1 -1
  19. package/src/core/state-detector.ts +1 -1
  20. package/src/core/target-manager.ts +1 -1
  21. package/src/index.ts +1 -1
  22. package/src/shared/files/index.ts +1 -1
  23. package/src/shared/processing/index.ts +1 -1
  24. package/src/targets/claude-code.ts +3 -3
  25. package/src/targets/opencode.ts +3 -3
  26. package/src/utils/agent-enhancer.ts +2 -2
  27. package/src/utils/{mcp-config.ts → config/mcp-config.ts} +4 -4
  28. package/src/utils/{paths.ts → config/paths.ts} +1 -1
  29. package/src/utils/{settings.ts → config/settings.ts} +1 -1
  30. package/src/utils/{target-config.ts → config/target-config.ts} +5 -5
  31. package/src/utils/{target-utils.ts → config/target-utils.ts} +3 -3
  32. package/src/utils/display/banner.ts +25 -0
  33. package/src/utils/display/status.ts +55 -0
  34. package/src/utils/{file-operations.ts → files/file-operations.ts} +2 -2
  35. package/src/utils/files/jsonc.ts +36 -0
  36. package/src/utils/{sync-utils.ts → files/sync-utils.ts} +3 -3
  37. package/src/utils/index.ts +42 -61
  38. package/src/utils/version.ts +47 -0
  39. package/src/components/benchmark-monitor.tsx +0 -331
  40. package/src/components/reindex-progress.tsx +0 -261
  41. package/src/composables/functional/index.ts +0 -14
  42. package/src/composables/functional/useEnvironment.ts +0 -171
  43. package/src/composables/functional/useFileSystem.ts +0 -139
  44. package/src/composables/index.ts +0 -4
  45. package/src/composables/useEnv.ts +0 -13
  46. package/src/composables/useRuntimeConfig.ts +0 -27
  47. package/src/core/ai-sdk.ts +0 -603
  48. package/src/core/app-factory.ts +0 -381
  49. package/src/core/builtin-agents.ts +0 -9
  50. package/src/core/command-system.ts +0 -550
  51. package/src/core/config-system.ts +0 -550
  52. package/src/core/connection-pool.ts +0 -390
  53. package/src/core/di-container.ts +0 -155
  54. package/src/core/headless-display.ts +0 -96
  55. package/src/core/interfaces/index.ts +0 -22
  56. package/src/core/interfaces/repository.interface.ts +0 -91
  57. package/src/core/interfaces/service.interface.ts +0 -133
  58. package/src/core/interfaces.ts +0 -96
  59. package/src/core/result.ts +0 -351
  60. package/src/core/service-config.ts +0 -252
  61. package/src/core/session-service.ts +0 -121
  62. package/src/core/storage-factory.ts +0 -115
  63. package/src/core/stream-handler.ts +0 -288
  64. package/src/core/type-utils.ts +0 -427
  65. package/src/core/unified-storage.ts +0 -456
  66. package/src/core/validation/limit.ts +0 -46
  67. package/src/core/validation/query.ts +0 -20
  68. package/src/db/auto-migrate.ts +0 -322
  69. package/src/db/base-database-client.ts +0 -144
  70. package/src/db/cache-db.ts +0 -218
  71. package/src/db/cache-schema.ts +0 -75
  72. package/src/db/database.ts +0 -70
  73. package/src/db/index.ts +0 -252
  74. package/src/db/memory-db.ts +0 -153
  75. package/src/db/memory-schema.ts +0 -29
  76. package/src/db/schema.ts +0 -289
  77. package/src/db/session-repository.ts +0 -733
  78. package/src/domains/index.ts +0 -6
  79. package/src/domains/utilities/index.ts +0 -6
  80. package/src/domains/utilities/time/index.ts +0 -5
  81. package/src/domains/utilities/time/tools.ts +0 -291
  82. package/src/services/agent-service.ts +0 -273
  83. package/src/services/evaluation-service.ts +0 -271
  84. package/src/services/functional/evaluation-logic.ts +0 -296
  85. package/src/services/functional/file-processor.ts +0 -273
  86. package/src/services/functional/index.ts +0 -12
  87. package/src/services/memory.service.ts +0 -476
  88. package/src/types/api/batch.ts +0 -108
  89. package/src/types/api/errors.ts +0 -118
  90. package/src/types/api/index.ts +0 -55
  91. package/src/types/api/requests.ts +0 -76
  92. package/src/types/api/responses.ts +0 -180
  93. package/src/types/api/websockets.ts +0 -85
  94. package/src/types/benchmark.ts +0 -49
  95. package/src/types/database.types.ts +0 -510
  96. package/src/types/memory-types.ts +0 -63
  97. package/src/utils/advanced-tokenizer.ts +0 -191
  98. package/src/utils/ai-model-fetcher.ts +0 -19
  99. package/src/utils/async-file-operations.ts +0 -516
  100. package/src/utils/audio-player.ts +0 -345
  101. package/src/utils/codebase-helpers.ts +0 -211
  102. package/src/utils/console-ui.ts +0 -79
  103. package/src/utils/database-errors.ts +0 -140
  104. package/src/utils/debug-logger.ts +0 -49
  105. package/src/utils/file-scanner.ts +0 -259
  106. package/src/utils/help.ts +0 -20
  107. package/src/utils/immutable-cache.ts +0 -106
  108. package/src/utils/jsonc.ts +0 -158
  109. package/src/utils/memory-tui.ts +0 -414
  110. package/src/utils/models-dev.ts +0 -91
  111. package/src/utils/parallel-operations.ts +0 -487
  112. package/src/utils/process-manager.ts +0 -155
  113. package/src/utils/prompts.ts +0 -120
  114. package/src/utils/search-tool-builder.ts +0 -214
  115. package/src/utils/session-manager.ts +0 -168
  116. package/src/utils/session-title.ts +0 -87
  117. package/src/utils/simplified-errors.ts +0 -410
  118. package/src/utils/template-engine.ts +0 -94
  119. package/src/utils/test-audio.ts +0 -71
  120. package/src/utils/todo-context.ts +0 -46
  121. package/src/utils/token-counter.ts +0 -288
  122. /package/src/utils/{cli-output.ts → display/cli-output.ts} +0 -0
  123. /package/src/utils/{logger.ts → display/logger.ts} +0 -0
  124. /package/src/utils/{notifications.ts → display/notifications.ts} +0 -0
  125. /package/src/utils/{secret-utils.ts → security/secret-utils.ts} +0 -0
  126. /package/src/utils/{security.ts → security/security.ts} +0 -0
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import chalk from 'chalk';
7
- import type { FlowOptions } from './flow-command.js';
7
+ import type { FlowOptions } from './flow/types.js';
8
8
  import { StateDetector, type ProjectState } from '../core/state-detector.js';
9
9
  import { UpgradeManager } from '../core/upgrade-manager.js';
10
10
  import { targetManager } from '../core/target-manager.js';
@@ -165,7 +165,7 @@ export async function checkSyncStatus(
165
165
  if (!state.target) return;
166
166
 
167
167
  try {
168
- const { buildSyncManifest } = await import('../utils/sync-utils.js');
168
+ const { buildSyncManifest } = await import('../utils/files/sync-utils.js');
169
169
  const target = targetManager.getTarget(state.target);
170
170
 
171
171
  if (target._tag === 'None') return;
@@ -210,9 +210,18 @@ export async function selectTarget(
210
210
  ): Promise<string | undefined> {
211
211
  // Force target selection when cleaning
212
212
  if (options.clean) {
213
- const targetId = await targetManager.promptForTargetSelection();
214
- console.log(chalk.green(`✅ Selected target: ${targetId}`));
215
- return targetId;
213
+ try {
214
+ const targetId = await targetManager.promptForTargetSelection();
215
+ console.log(chalk.green(`✅ Selected target: ${targetId}`));
216
+ return targetId;
217
+ } catch (error) {
218
+ // User cancelled with Ctrl+C - exit gracefully
219
+ if (error instanceof Error && error.name === 'ExitPromptError') {
220
+ console.log('\n');
221
+ process.exit(0);
222
+ }
223
+ throw error;
224
+ }
216
225
  }
217
226
 
218
227
  // Use existing target or option
@@ -14,7 +14,7 @@ import { exec } from 'node:child_process';
14
14
  import os from 'node:os';
15
15
  import { promisify } from 'node:util';
16
16
  import { Command } from 'commander';
17
- import { cli } from '../utils/cli-output.js';
17
+ import { cli } from '../utils/display/cli-output.js';
18
18
 
19
19
  const execAsync = promisify(exec);
20
20
 
@@ -7,8 +7,8 @@ import chalk from 'chalk';
7
7
  import ora from 'ora';
8
8
  import { targetManager } from '../core/target-manager.js';
9
9
  import { CLIError } from '../utils/error-handler.js';
10
- import { projectSettings } from '../utils/settings.js';
11
- import { validateTarget } from '../utils/target-config.js';
10
+ import { projectSettings } from '../utils/config/settings.js';
11
+ import { validateTarget } from '../utils/config/target-config.js';
12
12
  import { ConfigService } from '../services/config-service.js';
13
13
 
14
14
  export interface InitOptions {
@@ -47,7 +47,16 @@ export async function selectAndValidateTarget(options: InitOptions): Promise<str
47
47
 
48
48
  // Target selection (with UI prompt if needed)
49
49
  if (!targetId) {
50
- targetId = await targetManager.promptForTargetSelection();
50
+ try {
51
+ targetId = await targetManager.promptForTargetSelection();
52
+ } catch (error) {
53
+ // User cancelled with Ctrl+C - exit gracefully
54
+ if (error instanceof Error && error.name === 'ExitPromptError') {
55
+ console.log('\n');
56
+ process.exit(0);
57
+ }
58
+ throw error;
59
+ }
51
60
  }
52
61
 
53
62
  // Validate target
@@ -3,7 +3,7 @@ import path from 'node:path';
3
3
  import { Command } from 'commander';
4
4
  import { targetManager } from '../core/target-manager.js';
5
5
  import { CLIError } from '../utils/error-handler.js';
6
- import { getAgentsDir } from '../utils/paths.js';
6
+ import { getAgentsDir } from '../utils/config/paths.js';
7
7
 
8
8
  export async function loadAgentContent(agentName: string, agentFilePath?: string): Promise<string> {
9
9
  const { enhanceAgentContent } = await import('../utils/agent-enhancer.js');
@@ -2,7 +2,7 @@
2
2
  * Rules configuration
3
3
  */
4
4
 
5
- import { getRuleFile } from '../utils/paths.js';
5
+ import { getRuleFile } from '../utils/config/paths.js';
6
6
 
7
7
  export const CORE_RULES = {
8
8
  core: 'core.md',
@@ -3,7 +3,7 @@
3
3
  * Functional, composable error handling system
4
4
  */
5
5
 
6
- import { logger } from '../utils/logger.js';
6
+ import { logger } from '../utils/display/logger.js';
7
7
  import type { Result } from './result.js';
8
8
 
9
9
  /**
@@ -10,7 +10,7 @@
10
10
  */
11
11
 
12
12
  import chalk from 'chalk';
13
- import type { FlowOptions } from '../commands/flow-command.js';
13
+ import type { FlowOptions } from '../commands/flow/types.js';
14
14
 
15
15
  export interface LoopOptions {
16
16
  enabled: boolean;
@@ -1,7 +1,7 @@
1
1
  import fs from 'node:fs/promises';
2
2
  import path from 'node:path';
3
3
  import { fileURLToPath } from 'node:url';
4
- import { projectSettings } from '../utils/settings.js';
4
+ import { projectSettings } from '../utils/config/settings.js';
5
5
  import { targetManager } from './target-manager.js';
6
6
  import { ConfigService } from '../services/config-service.js';
7
7
 
@@ -10,7 +10,7 @@ import {
10
10
  isTargetImplemented,
11
11
  } from '../config/targets.js';
12
12
  import { getOrElse, isSome } from '../core/functional/option.js';
13
- import { projectSettings } from '../utils/settings.js';
13
+ import { projectSettings } from '../utils/config/settings.js';
14
14
 
15
15
  /**
16
16
  * Target Manager interface
package/src/index.ts CHANGED
@@ -15,8 +15,8 @@ import {
15
15
  setupCommand,
16
16
  doctorCommand,
17
17
  upgradeCommand,
18
- executeFlow,
19
18
  } from './commands/flow-command.js';
19
+ import { executeFlow } from './commands/flow/execute.js';
20
20
 
21
21
  // Read version from package.json
22
22
  const __filename = fileURLToPath(import.meta.url);
@@ -8,7 +8,7 @@ import {
8
8
  getFileInfo,
9
9
  readDirectorySafe,
10
10
  readFileSafe,
11
- } from '../../utils/file-operations.js';
11
+ } from '../../utils/files/file-operations.js';
12
12
  import type { ProcessResult } from '../types/index.js';
13
13
 
14
14
  /**
@@ -3,7 +3,7 @@
3
3
  */
4
4
 
5
5
  import path from 'node:path';
6
- import { ensureDirectory, readFileSafe, writeFileSafe } from '../../utils/file-operations.js';
6
+ import { ensureDirectory, readFileSafe, writeFileSafe } from '../../utils/files/file-operations.js';
7
7
  import { getLocalFileInfo } from '../files/index.js';
8
8
  import { log } from '../logging/index.js';
9
9
  import type { ProcessResult } from '../types/index.js';
@@ -8,9 +8,9 @@ import { MCPInstaller } from '../core/installers/mcp-installer.js';
8
8
  import type { AgentMetadata } from '../types/target-config.types.js';
9
9
  import type { CommonOptions, MCPServerConfigUnion, SetupResult, Target } from '../types.js';
10
10
  import { CLIError } from '../utils/error-handler.js';
11
- import { getAgentsDir, getSlashCommandsDir } from '../utils/paths.js';
12
- import { sanitize } from '../utils/security.js';
13
- import { fileUtils, generateHelpText, pathUtils, yamlUtils } from '../utils/target-utils.js';
11
+ import { getAgentsDir, getSlashCommandsDir } from '../utils/config/paths.js';
12
+ import { sanitize } from '../utils/security/security.js';
13
+ import { fileUtils, generateHelpText, pathUtils, yamlUtils } from '../utils/config/target-utils.js';
14
14
 
15
15
  /**
16
16
  * Claude Code target - composition approach with all original functionality
@@ -7,9 +7,9 @@ import { FileInstaller } from '../core/installers/file-installer.js';
7
7
  import { MCPInstaller } from '../core/installers/mcp-installer.js';
8
8
  import type { AgentMetadata } from '../types/target-config.types.js';
9
9
  import type { CommonOptions, MCPServerConfigUnion, SetupResult, Target } from '../types.js';
10
- import { getAgentsDir, getOutputStylesDir, getSlashCommandsDir } from '../utils/paths.js';
11
- import { secretUtils } from '../utils/secret-utils.js';
12
- import { fileUtils, generateHelpText, yamlUtils } from '../utils/target-utils.js';
10
+ import { getAgentsDir, getOutputStylesDir, getSlashCommandsDir } from '../utils/config/paths.js';
11
+ import { secretUtils } from '../utils/security/secret-utils.js';
12
+ import { fileUtils, generateHelpText, yamlUtils } from '../utils/config/target-utils.js';
13
13
  import { CLIError } from '../utils/error-handler.js';
14
14
 
15
15
  /**
@@ -12,8 +12,8 @@
12
12
 
13
13
  import fs from 'node:fs/promises';
14
14
  import path from 'node:path';
15
- import { getOutputStylesDir, getRulesDir } from './paths.js';
16
- import { yamlUtils } from './target-utils.js';
15
+ import { getOutputStylesDir, getRulesDir } from './config/paths.js';
16
+ import { yamlUtils } from './config/target-utils.js';
17
17
 
18
18
  /**
19
19
  * Load and combine rules and output styles
@@ -1,10 +1,10 @@
1
1
  import chalk from 'chalk';
2
2
 
3
3
  import inquirer from 'inquirer';
4
- import type { MCPServerID } from '../config/servers.js';
5
- import { getAllServerIDs, MCP_SERVER_REGISTRY } from '../config/servers.js';
6
- import { targetManager } from '../core/target-manager.js';
7
- import { getNestedProperty, setNestedProperty } from '../utils/target-config.js';
4
+ import type { MCPServerID } from '../../config/servers.js';
5
+ import { getAllServerIDs, MCP_SERVER_REGISTRY } from '../../config/servers.js';
6
+ import { targetManager } from '../../core/target-manager.js';
7
+ import { getNestedProperty, setNestedProperty } from './target-config.js';
8
8
 
9
9
  interface MCPConfigOptions {
10
10
  serverId?: MCPServerID;
@@ -13,7 +13,7 @@
13
13
  import fs from 'node:fs';
14
14
  import path from 'node:path';
15
15
  import { fileURLToPath } from 'node:url';
16
- import { pathSecurity } from './security.js';
16
+ import { pathSecurity } from '../security/security.js';
17
17
 
18
18
  /**
19
19
  * Find package root by walking up directory tree
@@ -5,7 +5,7 @@
5
5
 
6
6
  import fs from 'node:fs/promises';
7
7
  import path from 'node:path';
8
- import { type Result, success, tryCatchAsync } from '../core/functional/result.js';
8
+ import { type Result, success, tryCatchAsync } from '../../core/functional/result.js';
9
9
 
10
10
  export interface ProjectSettings {
11
11
  /** Default target for the project */
@@ -6,11 +6,11 @@ import {
6
6
  getSecretEnvVars,
7
7
  MCP_SERVER_REGISTRY,
8
8
  type MCPServerID,
9
- } from '../config/servers.js';
10
- import { targetManager } from '../core/target-manager.js';
11
- import { resolveConfig } from '../services/mcp-service.js';
12
- import { deleteNestedProperty, getNestedProperty, setNestedProperty } from './object-utils.js';
13
- import { secretUtils } from './secret-utils.js';
9
+ } from '../../config/servers.js';
10
+ import { targetManager } from '../../core/target-manager.js';
11
+ import { resolveConfig } from '../../services/mcp-service.js';
12
+ import { deleteNestedProperty, getNestedProperty, setNestedProperty } from '../object-utils.js';
13
+ import { secretUtils } from '../security/secret-utils.js';
14
14
 
15
15
  /**
16
16
  * Target-specific MCP configuration utilities
@@ -1,9 +1,9 @@
1
1
  import fs from 'node:fs/promises';
2
2
  import path from 'node:path';
3
3
  import { parse as parseYaml, stringify as stringifyYaml } from 'yaml';
4
- import type { MCPServerConfigUnion, TargetConfig } from '../types.js';
5
- import { readJSONCFile, writeJSONCFile } from './jsonc.js';
6
- import { pathSecurity, sanitize } from './security.js';
4
+ import type { MCPServerConfigUnion, TargetConfig } from '../../types.js';
5
+ import { readJSONCFile, writeJSONCFile } from '../files/jsonc.js';
6
+ import { pathSecurity, sanitize } from '../security/security.js';
7
7
 
8
8
  /**
9
9
  * File system utilities for targets
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Banner Display Utilities
3
+ * Welcome messages and branding
4
+ */
5
+
6
+ import chalk from 'chalk';
7
+ import boxen from 'boxen';
8
+
9
+ /**
10
+ * Display welcome banner
11
+ */
12
+ export function showWelcome(): void {
13
+ console.log(
14
+ boxen(
15
+ `${chalk.cyan.bold('Sylphx Flow')} ${chalk.dim('- AI-Powered Development Framework')}\n` +
16
+ `${chalk.dim('Auto-initialization • Smart upgrades • One-click launch')}`,
17
+ {
18
+ padding: 1,
19
+ margin: { bottom: 1 },
20
+ borderStyle: 'round',
21
+ borderColor: 'cyan',
22
+ }
23
+ )
24
+ );
25
+ }
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Status Display Utilities
3
+ * Project status and component information
4
+ */
5
+
6
+ import chalk from 'chalk';
7
+ import type { ProjectState } from '../../core/state-detector.js';
8
+ import { isVersionOutdated } from '../version.js';
9
+
10
+ /**
11
+ * Display project status
12
+ */
13
+ export async function showStatus(state: ProjectState): Promise<void> {
14
+ console.log(chalk.cyan.bold('📊 Project Status\n'));
15
+
16
+ if (!state.initialized) {
17
+ console.log(' ' + chalk.yellow('⚠ Not initialized'));
18
+ } else {
19
+ console.log(` ${chalk.green('✓')} Initialized (Flow v${state.version || 'unknown'})`);
20
+
21
+ if (state.target) {
22
+ const versionStr = state.targetVersion ? ` (v${state.targetVersion})` : '';
23
+ console.log(` ${chalk.green('✓')} Target platform: ${state.target}${versionStr}`);
24
+ }
25
+
26
+ // Component status
27
+ const components = state.components;
28
+ console.log(`\n ${chalk.cyan('Components:')}`);
29
+ console.log(` Agents: ${components.agents.installed ? chalk.green(`✓ ${components.agents.count}`) : chalk.red('✗')}`);
30
+ console.log(` Rules: ${components.rules.installed ? chalk.green(`✓ ${components.rules.count}`) : chalk.red('✗')}`);
31
+ console.log(` Hooks: ${components.hooks.installed ? chalk.green('✓') : chalk.red('✗')}`);
32
+ console.log(` MCP: ${components.mcp.installed ? chalk.green(`✓ ${components.mcp.serverCount} servers`) : chalk.red('✗')}`);
33
+ console.log(` Output styles: ${components.outputStyles.installed ? chalk.green('✓') : chalk.red('✗')}`);
34
+ console.log(` Slash commands: ${components.slashCommands.installed ? chalk.green(`✓ ${components.slashCommands.count}`) : chalk.red('✗')}`);
35
+
36
+ // Outdated warnings
37
+ if (state.outdated) {
38
+ console.log(`\n ${chalk.yellow('⚠')} Flow version outdated: ${state.version} → ${state.latestVersion}`);
39
+ }
40
+
41
+ if (state.targetVersion && state.targetLatestVersion &&
42
+ isVersionOutdated(state.targetVersion, state.targetLatestVersion)) {
43
+ console.log(` ${chalk.yellow('⚠')} ${state.target} update available: v${state.targetVersion} → v${state.targetLatestVersion}`);
44
+ }
45
+
46
+ if (state.lastUpdated) {
47
+ const days = Math.floor((Date.now() - state.lastUpdated.getTime()) / (1000 * 60 * 60 * 24));
48
+ if (days > 7) {
49
+ console.log(`\n ${chalk.yellow('⚠')} Last updated: ${days} days ago`);
50
+ }
51
+ }
52
+ }
53
+
54
+ console.log('');
55
+ }
@@ -5,8 +5,8 @@
5
5
 
6
6
  import fs from 'node:fs/promises';
7
7
  import path from 'node:path';
8
- import { pathSecurity } from './security.js';
9
- import { formatFileSize as formatFileSizeCore } from '../core/formatting/bytes.js';
8
+ import { pathSecurity } from '../security/security.js';
9
+ import { formatFileSize as formatFileSizeCore } from '../../core/formatting/bytes.js';
10
10
 
11
11
  export interface FileReadOptions {
12
12
  encoding?: BufferEncoding;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * JSONC (JSON with Comments) utilities
3
+ * Simple parser for JSON files that support comments
4
+ */
5
+
6
+ import fs from 'node:fs/promises';
7
+
8
+ /**
9
+ * Remove comments from JSONC content
10
+ */
11
+ function stripComments(content: string): string {
12
+ // Remove single-line comments (// ...)
13
+ let result = content.replace(/\/\/.*$/gm, '');
14
+
15
+ // Remove multi-line comments (/* ... */)
16
+ result = result.replace(/\/\*[\s\S]*?\*\//g, '');
17
+
18
+ return result;
19
+ }
20
+
21
+ /**
22
+ * Read and parse JSONC file
23
+ */
24
+ export async function readJSONCFile(filePath: string): Promise<any> {
25
+ const content = await fs.readFile(filePath, 'utf-8');
26
+ const stripped = stripComments(content);
27
+ return JSON.parse(stripped);
28
+ }
29
+
30
+ /**
31
+ * Write JSONC file (writes as regular JSON)
32
+ */
33
+ export async function writeJSONCFile(filePath: string, data: any): Promise<void> {
34
+ const content = JSON.stringify(data, null, 2);
35
+ await fs.writeFile(filePath, content, 'utf-8');
36
+ }
@@ -1,9 +1,9 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import chalk from 'chalk';
4
- import type { Target } from '../types.js';
5
- import { MCP_SERVER_REGISTRY } from '../config/servers.js';
6
- import { getAgentsDir, getSlashCommandsDir, getRulesDir } from './paths.js';
4
+ import type { Target } from '../../types.js';
5
+ import { MCP_SERVER_REGISTRY } from '../../config/servers.js';
6
+ import { getAgentsDir, getSlashCommandsDir, getRulesDir } from '../config/paths.js';
7
7
 
8
8
  /**
9
9
  * Scan directory for .md files and return basenames
@@ -1,78 +1,59 @@
1
1
  /**
2
2
  * Centralized utility exports
3
- * Provides both legacy organization and new feature-based organization
3
+ * Feature-based organization for better modularity
4
4
  */
5
5
 
6
6
  // ============================================================================
7
- // FEATURE-BASED ORGANIZATION (Removed - migrated to domains/ and services/)
7
+ // CONFIG & SETTINGS
8
8
  // ============================================================================
9
- // Features now organized in:
10
- // - src/domains/ for domain-specific logic
11
- // - src/services/ for shared infrastructure
9
+ export * from './config/settings.js';
10
+ export * from './config/mcp-config.js';
11
+ export * from './config/target-config.js';
12
+ export * from './config/target-utils.js';
13
+ export * from './config/paths.js';
12
14
 
13
15
  // ============================================================================
14
- // LEGACY ORGANIZATION (Backward Compatibility)
16
+ // DISPLAY & OUTPUT
15
17
  // ============================================================================
16
- // Direct exports for backward compatibility - @deprecated
18
+ export * from './display/banner.js';
19
+ export * from './display/status.js';
20
+ export * from './display/cli-output.js';
21
+ export * from './display/logger.js';
22
+ export * from './display/notifications.js';
17
23
 
18
- export * from './cache-storage.js';
19
- export * from './database-errors.js';
20
- // Database utilities
21
- export * from './drizzle-storage.js';
22
- // Error handling
23
- export * from './error-handler.js';
24
- // File operations
25
- export * from './file-operations.js';
26
- // JSONC utilities
27
- export * from './jsonc.js';
28
- // Logger utilities
29
- export * from './logger.js';
30
- export * from './memory-storage.js';
31
- // Path utilities
32
- export * from './paths.js';
33
- // Security utilities
34
- export * from './security.js';
35
- export * from './simplified-errors.js';
36
- // Target configuration
37
- export * from './target-config.js';
38
-
39
- // Search and indexing - moved to services/search/
24
+ // ============================================================================
25
+ // FILES & SYNC
26
+ // ============================================================================
27
+ export * from './files/file-operations.js';
28
+ export * from './files/sync-utils.js';
40
29
 
41
- // Command builder
42
- export * from './command-builder.js';
43
- // Console UI utilities
44
- export * from './console-ui.js';
45
- // Prompt utilities
46
- export * from './prompts.js';
47
- // Secret utilities
48
- export * from './secret-utils.js';
49
- // Template engine
50
- export * from './template-engine.js';
30
+ // ============================================================================
31
+ // SECURITY
32
+ // ============================================================================
33
+ export * from './security/security.js';
34
+ export * from './security/secret-utils.js';
51
35
 
52
- // Embeddings and TF-IDF - moved to services/search/
36
+ // ============================================================================
37
+ // ERROR HANDLING
38
+ // ============================================================================
39
+ export * from './error-handler.js';
53
40
 
54
- // Help utilities
55
- export * from './help.js';
41
+ // ============================================================================
42
+ // VERSIONING
43
+ // ============================================================================
44
+ export * from './version.js';
56
45
 
57
- // Target utilities
58
- export * from './target-utils.js';
46
+ // ============================================================================
47
+ // AGENTS
48
+ // ============================================================================
49
+ export * from './agent-enhancer.js';
59
50
 
60
- // Migration examples - removed (obsolete)
61
- // Test utilities - removed (obsolete)
51
+ // ============================================================================
52
+ // FUNCTIONAL PROGRAMMING
53
+ // ============================================================================
54
+ export * from './functional.js';
62
55
 
63
- // Shared utilities
56
+ // ============================================================================
57
+ // SHARED UTILITIES
58
+ // ============================================================================
64
59
  export * from '../shared/index.js';
65
-
66
- // Base indexer - moved to services/search/
67
-
68
- // LanceDB vector storage
69
- export * from './lancedb-vector-storage.js';
70
- // Separated storage
71
- export * from './separated-storage.js';
72
- // Settings utilities
73
- export * from './settings.js';
74
-
75
- // Target config types
76
- export * from './target-config.js';
77
- // Vector storage
78
- export * from './vector-storage.js';
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Version Utilities
3
+ * Semantic version comparison and validation
4
+ */
5
+
6
+ /**
7
+ * Compare two semantic version strings
8
+ * @returns Negative if v1 < v2, positive if v1 > v2, zero if equal
9
+ */
10
+ export function compareVersions(v1: string, v2: string): number {
11
+ const parts1 = v1.split('.').map(Number);
12
+ const parts2 = v2.split('.').map(Number);
13
+
14
+ for (let i = 0; i < Math.min(parts1.length, parts2.length); i++) {
15
+ if (parts1[i] !== parts2[i]) {
16
+ return parts1[i] - parts2[i];
17
+ }
18
+ }
19
+
20
+ return parts1.length - parts2.length;
21
+ }
22
+
23
+ /**
24
+ * Check if current version is outdated compared to latest
25
+ */
26
+ export function isVersionOutdated(current: string, latest: string): boolean {
27
+ try {
28
+ return compareVersions(current, latest) < 0;
29
+ } catch {
30
+ return false;
31
+ }
32
+ }
33
+
34
+ /**
35
+ * Parse version string into components
36
+ */
37
+ export function parseVersion(version: string): { major: number; minor: number; patch: number } | null {
38
+ const parts = version.split('.').map(Number);
39
+ if (parts.length < 3 || parts.some(isNaN)) {
40
+ return null;
41
+ }
42
+ return {
43
+ major: parts[0],
44
+ minor: parts[1],
45
+ patch: parts[2],
46
+ };
47
+ }