@sylphx/flow 1.7.0 → 1.8.1

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 (131) hide show
  1. package/CHANGELOG.md +78 -0
  2. package/assets/agents/coder.md +72 -119
  3. package/assets/agents/orchestrator.md +26 -90
  4. package/assets/agents/reviewer.md +76 -47
  5. package/assets/agents/writer.md +82 -63
  6. package/assets/output-styles/silent.md +141 -8
  7. package/assets/rules/code-standards.md +9 -33
  8. package/assets/rules/core.md +67 -59
  9. package/package.json +2 -12
  10. package/src/commands/flow/execute.ts +470 -0
  11. package/src/commands/flow/index.ts +11 -0
  12. package/src/commands/flow/prompt.ts +35 -0
  13. package/src/commands/flow/setup.ts +312 -0
  14. package/src/commands/flow/targets.ts +18 -0
  15. package/src/commands/flow/types.ts +47 -0
  16. package/src/commands/flow-command.ts +18 -967
  17. package/src/commands/flow-orchestrator.ts +14 -5
  18. package/src/commands/hook-command.ts +1 -1
  19. package/src/commands/init-core.ts +12 -3
  20. package/src/commands/run-command.ts +1 -1
  21. package/src/config/rules.ts +1 -1
  22. package/src/core/error-handling.ts +1 -1
  23. package/src/core/loop-controller.ts +1 -1
  24. package/src/core/state-detector.ts +1 -1
  25. package/src/core/target-manager.ts +1 -1
  26. package/src/index.ts +1 -1
  27. package/src/shared/files/index.ts +1 -1
  28. package/src/shared/processing/index.ts +1 -1
  29. package/src/targets/claude-code.ts +3 -3
  30. package/src/targets/opencode.ts +3 -3
  31. package/src/utils/agent-enhancer.ts +2 -2
  32. package/src/utils/{mcp-config.ts → config/mcp-config.ts} +4 -4
  33. package/src/utils/{paths.ts → config/paths.ts} +1 -1
  34. package/src/utils/{settings.ts → config/settings.ts} +1 -1
  35. package/src/utils/{target-config.ts → config/target-config.ts} +5 -5
  36. package/src/utils/{target-utils.ts → config/target-utils.ts} +3 -3
  37. package/src/utils/display/banner.ts +25 -0
  38. package/src/utils/display/status.ts +55 -0
  39. package/src/utils/{file-operations.ts → files/file-operations.ts} +2 -2
  40. package/src/utils/files/jsonc.ts +36 -0
  41. package/src/utils/{sync-utils.ts → files/sync-utils.ts} +3 -3
  42. package/src/utils/index.ts +42 -61
  43. package/src/utils/version.ts +47 -0
  44. package/src/components/benchmark-monitor.tsx +0 -331
  45. package/src/components/reindex-progress.tsx +0 -261
  46. package/src/composables/functional/index.ts +0 -14
  47. package/src/composables/functional/useEnvironment.ts +0 -171
  48. package/src/composables/functional/useFileSystem.ts +0 -139
  49. package/src/composables/index.ts +0 -4
  50. package/src/composables/useEnv.ts +0 -13
  51. package/src/composables/useRuntimeConfig.ts +0 -27
  52. package/src/core/ai-sdk.ts +0 -603
  53. package/src/core/app-factory.ts +0 -381
  54. package/src/core/builtin-agents.ts +0 -9
  55. package/src/core/command-system.ts +0 -550
  56. package/src/core/config-system.ts +0 -550
  57. package/src/core/connection-pool.ts +0 -390
  58. package/src/core/di-container.ts +0 -155
  59. package/src/core/headless-display.ts +0 -96
  60. package/src/core/interfaces/index.ts +0 -22
  61. package/src/core/interfaces/repository.interface.ts +0 -91
  62. package/src/core/interfaces/service.interface.ts +0 -133
  63. package/src/core/interfaces.ts +0 -96
  64. package/src/core/result.ts +0 -351
  65. package/src/core/service-config.ts +0 -252
  66. package/src/core/session-service.ts +0 -121
  67. package/src/core/storage-factory.ts +0 -115
  68. package/src/core/stream-handler.ts +0 -288
  69. package/src/core/type-utils.ts +0 -427
  70. package/src/core/unified-storage.ts +0 -456
  71. package/src/core/validation/limit.ts +0 -46
  72. package/src/core/validation/query.ts +0 -20
  73. package/src/db/auto-migrate.ts +0 -322
  74. package/src/db/base-database-client.ts +0 -144
  75. package/src/db/cache-db.ts +0 -218
  76. package/src/db/cache-schema.ts +0 -75
  77. package/src/db/database.ts +0 -70
  78. package/src/db/index.ts +0 -252
  79. package/src/db/memory-db.ts +0 -153
  80. package/src/db/memory-schema.ts +0 -29
  81. package/src/db/schema.ts +0 -289
  82. package/src/db/session-repository.ts +0 -733
  83. package/src/domains/index.ts +0 -6
  84. package/src/domains/utilities/index.ts +0 -6
  85. package/src/domains/utilities/time/index.ts +0 -5
  86. package/src/domains/utilities/time/tools.ts +0 -291
  87. package/src/services/agent-service.ts +0 -273
  88. package/src/services/evaluation-service.ts +0 -271
  89. package/src/services/functional/evaluation-logic.ts +0 -296
  90. package/src/services/functional/file-processor.ts +0 -273
  91. package/src/services/functional/index.ts +0 -12
  92. package/src/services/memory.service.ts +0 -476
  93. package/src/types/api/batch.ts +0 -108
  94. package/src/types/api/errors.ts +0 -118
  95. package/src/types/api/index.ts +0 -55
  96. package/src/types/api/requests.ts +0 -76
  97. package/src/types/api/responses.ts +0 -180
  98. package/src/types/api/websockets.ts +0 -85
  99. package/src/types/benchmark.ts +0 -49
  100. package/src/types/database.types.ts +0 -510
  101. package/src/types/memory-types.ts +0 -63
  102. package/src/utils/advanced-tokenizer.ts +0 -191
  103. package/src/utils/ai-model-fetcher.ts +0 -19
  104. package/src/utils/async-file-operations.ts +0 -516
  105. package/src/utils/audio-player.ts +0 -345
  106. package/src/utils/codebase-helpers.ts +0 -211
  107. package/src/utils/console-ui.ts +0 -79
  108. package/src/utils/database-errors.ts +0 -140
  109. package/src/utils/debug-logger.ts +0 -49
  110. package/src/utils/file-scanner.ts +0 -259
  111. package/src/utils/help.ts +0 -20
  112. package/src/utils/immutable-cache.ts +0 -106
  113. package/src/utils/jsonc.ts +0 -158
  114. package/src/utils/memory-tui.ts +0 -414
  115. package/src/utils/models-dev.ts +0 -91
  116. package/src/utils/parallel-operations.ts +0 -487
  117. package/src/utils/process-manager.ts +0 -155
  118. package/src/utils/prompts.ts +0 -120
  119. package/src/utils/search-tool-builder.ts +0 -214
  120. package/src/utils/session-manager.ts +0 -168
  121. package/src/utils/session-title.ts +0 -87
  122. package/src/utils/simplified-errors.ts +0 -410
  123. package/src/utils/template-engine.ts +0 -94
  124. package/src/utils/test-audio.ts +0 -71
  125. package/src/utils/todo-context.ts +0 -46
  126. package/src/utils/token-counter.ts +0 -288
  127. /package/src/utils/{cli-output.ts → display/cli-output.ts} +0 -0
  128. /package/src/utils/{logger.ts → display/logger.ts} +0 -0
  129. /package/src/utils/{notifications.ts → display/notifications.ts} +0 -0
  130. /package/src/utils/{secret-utils.ts → security/secret-utils.ts} +0 -0
  131. /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
+ }