@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
@@ -0,0 +1,312 @@
1
+ /**
2
+ * Setup Phase for Flow Command
3
+ * One-time initialization and preparation for command execution
4
+ */
5
+
6
+ import chalk from 'chalk';
7
+ import { targetManager } from '../../core/target-manager.js';
8
+ import { StateDetector, type ProjectState } from '../../core/state-detector.js';
9
+ import { projectSettings } from '../../utils/config/settings.js';
10
+ import { showWelcome } from '../../utils/display/banner.js';
11
+ import { showStatus } from '../../utils/display/status.js';
12
+ import { loadAgentContent, extractAgentInstructions } from '../run-command.js';
13
+ import type { RunCommandOptions } from '../../types.js';
14
+ import type { FlowOptions, SetupContext } from './types.js';
15
+
16
+ /**
17
+ * Execute setup phase once (for loop mode)
18
+ * Returns context needed for repeated command execution
19
+ */
20
+ export async function executeSetupPhase(prompt: string | undefined, options: FlowOptions): Promise<SetupContext> {
21
+ // Quick mode: enable useDefaults and skip prompts
22
+ if (options.quick) {
23
+ options.useDefaults = true;
24
+ console.log(chalk.cyan('⚡ Quick mode enabled - using saved defaults\n'));
25
+ }
26
+
27
+ // Import orchestrator functions
28
+ const {
29
+ checkUpgrades,
30
+ checkComponentIntegrity,
31
+ } = await import('../flow-orchestrator.js');
32
+
33
+ // Show welcome banner (only once)
34
+ showWelcome();
35
+
36
+ let selectedTarget: string | undefined;
37
+ let state: ProjectState | undefined;
38
+
39
+ // Determine target
40
+ const initialTarget = options.target || (await projectSettings.getDefaultTarget());
41
+
42
+ // Detect state if we have a target
43
+ if (initialTarget && !options.sync) {
44
+ const detector = new StateDetector();
45
+
46
+ if (options.verbose) {
47
+ console.log(chalk.dim('🤔 Checking project status...\n'));
48
+ }
49
+
50
+ state = await detector.detect();
51
+
52
+ if (options.verbose) {
53
+ await showStatus(state);
54
+ }
55
+
56
+ // Check for upgrades
57
+ if (!options.quick) {
58
+ await checkUpgrades(state, options);
59
+ }
60
+
61
+ // Check component integrity
62
+ await checkComponentIntegrity(state, options);
63
+ }
64
+
65
+ // Initialize if needed
66
+ const shouldInitialize =
67
+ !state?.initialized ||
68
+ options.sync ||
69
+ options.repair ||
70
+ options.initOnly;
71
+
72
+ if (shouldInitialize) {
73
+ selectedTarget = await initializeWithTarget(options);
74
+ }
75
+
76
+ // Resolve target
77
+ const targetForResolution = resolveTargetPriority(options.target, state?.target, selectedTarget);
78
+
79
+ if (!targetForResolution) {
80
+ console.error(chalk.red.bold('✗ No target selected. Use --target or run init first.'));
81
+ process.exit(1);
82
+ }
83
+
84
+ const resolvedTarget = await targetManager.resolveTarget({
85
+ target: targetForResolution,
86
+ allowSelection: false,
87
+ });
88
+
89
+ console.log(chalk.cyan.bold(`━━━ 🎯 Launching ${resolvedTarget}\n`));
90
+
91
+ // Validate target support
92
+ await validateTargetSupport(resolvedTarget);
93
+
94
+ // Handle Claude Code specific setup
95
+ if (resolvedTarget === 'claude-code') {
96
+ await setupClaudeCode(options);
97
+ }
98
+
99
+ const agent = options.agent || 'coder';
100
+ const verbose = options.verbose || false;
101
+
102
+ if (verbose || options.runOnly || !options.quick) {
103
+ console.log(` 🤖 Agent: ${chalk.cyan(agent)}`);
104
+ console.log(` 🎯 Target: ${chalk.cyan(resolvedTarget)}`);
105
+ if (prompt) {
106
+ console.log(` 💬 Prompt: ${chalk.dim(prompt)}\n`);
107
+ } else {
108
+ console.log(` 💬 Mode: ${chalk.dim('Interactive')}\n`);
109
+ }
110
+ }
111
+
112
+ // Load agent and prepare prompts
113
+ const agentContent = await loadAgentContent(agent, options.agentFile);
114
+ const agentInstructions = extractAgentInstructions(agentContent);
115
+ const systemPrompt = `AGENT INSTRUCTIONS:\n${agentInstructions}`;
116
+
117
+ // Prepare run options
118
+ const runOptions: RunCommandOptions = {
119
+ target: resolvedTarget,
120
+ verbose,
121
+ dryRun: options.dryRun,
122
+ agent,
123
+ agentFile: options.agentFile,
124
+ prompt,
125
+ print: options.print,
126
+ continue: options.continue,
127
+ };
128
+
129
+ return {
130
+ resolvedTarget,
131
+ initializedSuccessfully: true,
132
+ systemPrompt,
133
+ runOptions,
134
+ };
135
+ }
136
+
137
+ /**
138
+ * Initialize project with target selection and component installation
139
+ */
140
+ async function initializeWithTarget(options: FlowOptions): Promise<string | undefined> {
141
+ let selectedTarget: string | undefined;
142
+
143
+ try {
144
+ const { selectAndValidateTarget, previewDryRun, installComponents } =
145
+ await import('../init-core.js');
146
+
147
+ const initOptions = {
148
+ target: options.target,
149
+ verbose: options.verbose || false,
150
+ dryRun: options.dryRun || false,
151
+ clear: options.sync || false,
152
+ mcp: options.mcp !== false,
153
+ agents: options.agents !== false,
154
+ rules: options.rules !== false,
155
+ outputStyles: options.outputStyles !== false,
156
+ slashCommands: options.slashCommands !== false,
157
+ hooks: options.hooks !== false,
158
+ };
159
+
160
+ // Handle sync mode - delete template files first
161
+ if (options.sync && !options.dryRun) {
162
+ selectedTarget = await handleSyncMode(initOptions);
163
+ } else if (!options.sync) {
164
+ const targetId = await selectAndValidateTarget(initOptions);
165
+ selectedTarget = targetId;
166
+ }
167
+
168
+ if (options.dryRun) {
169
+ // Ensure we have a target ID for dry run
170
+ if (!selectedTarget) {
171
+ const targetId = await selectAndValidateTarget(initOptions);
172
+ selectedTarget = targetId;
173
+ }
174
+
175
+ await previewDryRun(selectedTarget, initOptions);
176
+ console.log(chalk.dim('✓ Initialization dry run complete\n'));
177
+ } else {
178
+ // Ensure we have a target ID for installation
179
+ if (!selectedTarget) {
180
+ const targetId = await selectAndValidateTarget(initOptions);
181
+ selectedTarget = targetId;
182
+ }
183
+
184
+ await installComponents(selectedTarget, initOptions);
185
+ console.log(chalk.green.bold('✓ Initialization complete\n'));
186
+ }
187
+ } catch (error) {
188
+ console.error(chalk.red.bold('✗ Initialization failed:'), error);
189
+ process.exit(1);
190
+ }
191
+
192
+ return selectedTarget;
193
+ }
194
+
195
+ /**
196
+ * Handle sync mode: delete templates then reinstall
197
+ */
198
+ async function handleSyncMode(initOptions: any): Promise<string> {
199
+ const { buildSyncManifest, showSyncPreview, selectUnknownFilesToRemove, showFinalSummary, confirmSync, executeSyncDelete, removeMCPServers, removeHooks } = await import('../../utils/files/sync-utils.js');
200
+ const { selectAndValidateTarget } = await import('../init-core.js');
201
+
202
+ // Need target to build manifest
203
+ const targetId = await selectAndValidateTarget(initOptions);
204
+
205
+ const targetOption = targetManager.getTarget(targetId);
206
+ if (targetOption._tag === 'None') {
207
+ throw new Error(`Target not found: ${targetId}`);
208
+ }
209
+
210
+ const target = targetOption.value;
211
+ const manifest = await buildSyncManifest(process.cwd(), target);
212
+
213
+ // Show preview
214
+ console.log(chalk.cyan.bold('━━━ 🔄 Synchronizing Files\n'));
215
+ showSyncPreview(manifest, process.cwd(), target);
216
+
217
+ // Select unknown files to remove
218
+ const selectedUnknowns = await selectUnknownFilesToRemove(manifest);
219
+
220
+ // Show final summary
221
+ showFinalSummary(manifest, selectedUnknowns);
222
+
223
+ // Confirm
224
+ const confirmed = await confirmSync();
225
+ if (!confirmed) {
226
+ console.log(chalk.yellow('\n✗ Sync cancelled\n'));
227
+ process.exit(0);
228
+ }
229
+
230
+ // Execute deletion
231
+ const { templates, unknowns } = await executeSyncDelete(manifest, selectedUnknowns);
232
+
233
+ // Remove MCP servers
234
+ let mcpRemoved = 0;
235
+ if (selectedUnknowns.mcpServers.length > 0) {
236
+ mcpRemoved = await removeMCPServers(process.cwd(), selectedUnknowns.mcpServers);
237
+ }
238
+
239
+ // Remove hooks
240
+ let hooksRemoved = 0;
241
+ if (selectedUnknowns.hooks.length > 0) {
242
+ hooksRemoved = await removeHooks(process.cwd(), selectedUnknowns.hooks);
243
+ }
244
+
245
+ // Summary
246
+ console.log(chalk.green(`\n✓ Synced ${templates} templates`));
247
+ const totalRemoved = unknowns + mcpRemoved + hooksRemoved;
248
+ if (totalRemoved > 0) {
249
+ console.log(chalk.green(`✓ Removed ${totalRemoved} items`));
250
+ }
251
+ const totalSelected = selectedUnknowns.files.length + selectedUnknowns.mcpServers.length + selectedUnknowns.hooks.length;
252
+ const preserved = manifest.agents.unknown.length + manifest.slashCommands.unknown.length + manifest.rules.unknown.length + manifest.mcpServers.notInRegistry.length + manifest.hooks.orphaned.length - totalSelected;
253
+ if (preserved > 0) {
254
+ console.log(chalk.green(`✓ Preserved ${preserved} custom items`));
255
+ }
256
+ console.log('');
257
+
258
+ return targetId;
259
+ }
260
+
261
+ /**
262
+ * Resolve target priority: options > state > selected
263
+ */
264
+ function resolveTargetPriority(
265
+ optionsTarget: string | undefined,
266
+ stateTarget: string | undefined,
267
+ selectedTarget: string | undefined
268
+ ): string | undefined {
269
+ return selectedTarget || optionsTarget || stateTarget;
270
+ }
271
+
272
+ /**
273
+ * Validate that target supports command execution
274
+ */
275
+ async function validateTargetSupport(resolvedTarget: string): Promise<void> {
276
+ const { getTargetsWithCommandSupport } = await import('../../config/targets.js');
277
+ const supportedTargets = getTargetsWithCommandSupport().map(t => t.id);
278
+
279
+ if (!supportedTargets.includes(resolvedTarget)) {
280
+ console.log(chalk.red.bold('✗ Unsupported target platform\n'));
281
+ console.log(chalk.yellow(`Target '${resolvedTarget}' does not support agent execution.`));
282
+ console.log(chalk.cyan(`Supported platforms: ${supportedTargets.join(', ')}\n`));
283
+ console.log(chalk.dim('Tip: Use --target claude-code to specify Claude Code platform'));
284
+ console.log(chalk.dim('Example: bun dev:flow --target claude-code\n'));
285
+ process.exit(1);
286
+ }
287
+ }
288
+
289
+ /**
290
+ * Setup Claude Code provider and agent
291
+ */
292
+ async function setupClaudeCode(options: FlowOptions): Promise<void> {
293
+ const { SmartConfigService } = await import('../../services/smart-config-service.js');
294
+ const { ConfigService } = await import('../../services/config-service.js');
295
+
296
+ if (!(await ConfigService.hasInitialSetup())) {
297
+ console.log(chalk.cyan('🔑 First-time setup for Claude Code\n'));
298
+ await SmartConfigService.initialSetup();
299
+ console.log(chalk.green('✓ Setup complete!\n'));
300
+ }
301
+
302
+ const runtimeChoices = await SmartConfigService.selectRuntimeChoices({
303
+ selectProvider: options.selectProvider,
304
+ selectAgent: options.selectAgent,
305
+ useDefaults: options.useDefaults,
306
+ provider: options.provider,
307
+ agent: options.agent,
308
+ });
309
+
310
+ await SmartConfigService.setupEnvironment(runtimeChoices.provider!);
311
+ options.agent = runtimeChoices.agent;
312
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Target Management for Flow Commands
3
+ */
4
+
5
+ import { targetManager } from '../../core/target-manager.js';
6
+
7
+ /**
8
+ * Get executable targets
9
+ */
10
+ export function getExecutableTargets(): string[] {
11
+ return targetManager.getImplementedTargetIDs().filter((targetId) => {
12
+ const targetOption = targetManager.getTarget(targetId);
13
+ if (targetOption._tag === 'None') {
14
+ return false;
15
+ }
16
+ return targetOption.value.executeCommand !== undefined;
17
+ });
18
+ }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Flow Command Types
3
+ */
4
+
5
+ import type { RunCommandOptions } from '../../types.js';
6
+
7
+ export interface FlowOptions {
8
+ target?: string;
9
+ verbose?: boolean;
10
+ dryRun?: boolean;
11
+ sync?: boolean;
12
+ initOnly?: boolean;
13
+ runOnly?: boolean;
14
+ repair?: boolean;
15
+ upgrade?: boolean;
16
+ upgradeTarget?: boolean;
17
+ mcp?: boolean;
18
+ agents?: boolean;
19
+ rules?: boolean;
20
+ outputStyles?: boolean;
21
+ slashCommands?: boolean;
22
+ hooks?: boolean;
23
+ agent?: string;
24
+ agentFile?: string;
25
+
26
+ // Smart configuration options
27
+ selectProvider?: boolean;
28
+ selectAgent?: boolean;
29
+ useDefaults?: boolean;
30
+ provider?: string;
31
+ quick?: boolean;
32
+
33
+ // Execution modes
34
+ print?: boolean;
35
+ continue?: boolean;
36
+
37
+ // Loop mode
38
+ loop?: number;
39
+ maxRuns?: number;
40
+ }
41
+
42
+ export interface SetupContext {
43
+ resolvedTarget: string;
44
+ initializedSuccessfully: boolean;
45
+ systemPrompt?: string;
46
+ runOptions?: RunCommandOptions;
47
+ }