@sylphx/flow 1.8.1 → 2.0.0

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.
@@ -11,49 +11,23 @@ import { StateDetector } from '../core/state-detector.js';
11
11
  import { UpgradeManager } from '../core/upgrade-manager.js';
12
12
  import { showWelcome } from '../utils/display/banner.js';
13
13
  import { showStatus } from '../utils/display/status.js';
14
- import { executeFlow } from './flow/execute.js';
14
+ import { executeFlow } from './flow/execute-v2.js';
15
15
  import type { FlowOptions } from './flow/types.js';
16
16
 
17
17
  /**
18
- * Smart flow command
18
+ * Flow command (simplified for attach mode)
19
19
  */
20
20
  export const flowCommand = new Command('flow')
21
- .description('Intelligent development flow (auto-detect state and act accordingly)')
22
-
23
- // Smart options
24
- .option('--init-only', 'Only initialize, do not run')
25
- .option('--run-only', 'Only run, skip initialization')
26
- .option('--sync', 'Synchronize with Flow templates (delete and re-install template files)')
27
- .option('--upgrade', 'Upgrade Sylphx Flow to latest version')
28
- .option('--upgrade-target', 'Upgrade target platform (Claude Code/OpenCode)')
29
-
30
- // Smart configuration options
31
- .option('--quick', 'Quick mode: use saved defaults and skip all prompts')
32
- .option('--select-provider', 'Prompt to select provider each run')
33
- .option('--select-agent', 'Prompt to select agent each run')
34
- .option('--use-defaults', 'Skip prompts, use saved defaults')
35
- .option('--provider <provider>', 'Override provider for this run (anthropic|z.ai|kimi)')
36
-
37
- // Init options
38
- .option('--target <type>', 'Target platform (opencode, claude-code, auto-detect)')
39
- .option('--verbose', 'Show detailed output')
40
- .option('--dry-run', 'Show what would be done without making changes')
41
- .option('--no-mcp', 'Skip MCP installation')
42
- .option('--no-agents', 'Skip agents installation')
43
- .option('--no-rules', 'Skip rules installation')
44
- .option('--no-output-styles', 'Skip output styles installation')
45
- .option('--no-slash-commands', 'Skip slash commands installation')
46
- .option('--no-hooks', 'Skip hooks setup')
47
-
48
- // Run options
21
+ .description('Run Flow with automatic environment attach')
22
+
23
+ // Core options
49
24
  .option('--agent <name>', 'Agent to use (default: coder)', 'coder')
50
25
  .option('--agent-file <path>', 'Load agent from specific file')
26
+ .option('--verbose', 'Show detailed output')
27
+ .option('--dry-run', 'Show what would be done without making changes')
51
28
  .option('-p, --print', 'Headless print mode (output only, no interactive)')
52
29
  .option('-c, --continue', 'Continue previous conversation (requires print mode)')
53
-
54
- // Loop options
55
- .option('--loop [interval]', 'Loop mode: run repeatedly (optional cooldown in seconds)')
56
- .option('--max-runs <number>', 'Maximum loop iterations (default: infinite)', parseInt)
30
+ .option('--merge', 'Merge Flow settings with existing settings (default: replace all)')
57
31
 
58
32
  // Prompt argument
59
33
  .argument('[prompt]', 'Prompt to execute with agent (optional, supports @file.txt for file input)')
@@ -63,34 +37,17 @@ export const flowCommand = new Command('flow')
63
37
  });
64
38
 
65
39
  /**
66
- * Setup command - alias for `flow --init-only`
67
- * Kept for backward compatibility
40
+ * Setup command - deprecated (attach mode is automatic)
68
41
  */
69
42
  export const setupCommand = new Command('setup')
70
- .description('Initialize project configuration (alias for: flow --init-only)')
43
+ .description('[DEPRECATED] No longer needed - Flow uses automatic attach mode')
71
44
  .action(async () => {
72
- console.log(chalk.yellow(' The "setup" command is deprecated.'));
73
- console.log(chalk.yellow(' Please use: flow --init-only\n'));
74
-
75
- showWelcome();
76
-
77
- const { runInit } = await import('./init-command.js');
78
- await runInit({
79
- target: undefined,
80
- verbose: false,
81
- dryRun: false,
82
- clear: false,
83
- mcp: true,
84
- agents: true,
85
- rules: true,
86
- outputStyles: true,
87
- slashCommands: true,
88
- hooks: true,
89
- helpOption: () => {},
90
- });
91
-
92
- console.log(chalk.green('\n✅ Setup complete!'));
93
- console.log(chalk.dim('\nNext time, use: flow --init-only'));
45
+ console.log(chalk.yellow('⚠️ The "setup" command is deprecated.\n'));
46
+ console.log(chalk.cyan('Flow now uses automatic attach mode:'));
47
+ console.log(chalk.dim(' • No installation needed'));
48
+ console.log(chalk.dim(' • Environment attached automatically'));
49
+ console.log(chalk.dim(' • Restored on exit\n'));
50
+ console.log(chalk.green('✨ Just run: sylphx-flow "your prompt"\n'));
94
51
  });
95
52
 
96
53
  /**
@@ -193,11 +150,12 @@ export const doctorCommand = new Command('doctor')
193
150
  export const upgradeCommand = new Command('upgrade')
194
151
  .description('Upgrade Sylphx Flow and components')
195
152
  .option('--check', 'Only check for updates, do not upgrade')
153
+ .option('--auto', 'Automatically install updates via npm')
196
154
  .option('--components', 'Upgrade components (agents, rules, etc)', true)
197
155
  .option('--target', 'Upgrade target platform (Claude Code/OpenCode)')
198
156
  .option('--verbose', 'Show detailed output')
199
157
  .action(async (options) => {
200
- console.log(chalk.cyan.bold('📦 检查更新\n'));
158
+ console.log(chalk.cyan.bold('📦 Checking for updates\n'));
201
159
 
202
160
  const detector = new StateDetector();
203
161
  const upgradeManager = new UpgradeManager();
@@ -205,7 +163,7 @@ export const upgradeCommand = new Command('upgrade')
205
163
  const updates = await upgradeManager.checkUpdates();
206
164
 
207
165
  if (!updates.flowUpdate && !updates.targetUpdate) {
208
- console.log(chalk.green('✓ 所有组件已是最新版本\n'));
166
+ console.log(chalk.green('✓ All components are up to date\n'));
209
167
  return;
210
168
  }
211
169
 
@@ -219,7 +177,7 @@ export const upgradeCommand = new Command('upgrade')
219
177
 
220
178
  // Check only
221
179
  if (options.check) {
222
- console.log('\n' + chalk.dim('使用 --no-check 或省略参数进行升级'));
180
+ console.log('\n' + chalk.dim('Run without --check to upgrade'));
223
181
  return;
224
182
  }
225
183
 
@@ -229,13 +187,13 @@ export const upgradeCommand = new Command('upgrade')
229
187
  {
230
188
  type: 'confirm',
231
189
  name: 'confirm',
232
- message: '确认升级到最新版本?',
190
+ message: 'Upgrade to latest version?',
233
191
  default: true,
234
192
  },
235
193
  ]);
236
194
 
237
195
  if (!confirm) {
238
- console.log(chalk.dim('\n升级已取消'));
196
+ console.log(chalk.dim('\nUpgrade cancelled'));
239
197
  return;
240
198
  }
241
199
 
@@ -243,16 +201,21 @@ export const upgradeCommand = new Command('upgrade')
243
201
  console.log('');
244
202
 
245
203
  const state = await detector.detect();
204
+ const autoInstall = options.auto || false;
246
205
 
247
206
  if (updates.flowUpdate) {
248
- console.log(chalk.cyan.bold('\n━ 升级 Sylphx Flow\n'));
249
- await upgradeManager.upgradeFlow(state);
207
+ console.log(chalk.cyan.bold('\n━ Upgrading Sylphx Flow\n'));
208
+ await upgradeManager.upgradeFlow(state, autoInstall);
250
209
  }
251
210
 
252
211
  if (updates.targetUpdate && options.target) {
253
- console.log(chalk.cyan.bold('\n━ 升级 Target\n'));
254
- await upgradeManager.upgradeTarget(state);
212
+ console.log(chalk.cyan.bold('\n━ Upgrading Target\n'));
213
+ await upgradeManager.upgradeTarget(state, autoInstall);
255
214
  }
256
215
 
257
- console.log(chalk.green('\n✓ 升级完成\n'));
216
+ console.log(chalk.green('\n✓ Upgrade complete\n'));
217
+
218
+ if (!autoInstall) {
219
+ console.log(chalk.dim('💡 Tip: Use --auto flag to automatically install updates via npm\n'));
220
+ }
258
221
  });
@@ -8,6 +8,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';
11
+ import { detectPackageManager, getUpgradeCommand } from '../utils/package-manager-detector.js';
11
12
 
12
13
  /**
13
14
  * Step 1: Check for available upgrades
@@ -18,71 +19,33 @@ export async function checkUpgrades(
18
19
  ): Promise<void> {
19
20
  if (options.initOnly || options.runOnly) return;
20
21
 
22
+ const upgradeManager = new UpgradeManager();
23
+ const updates = await upgradeManager.checkUpdates();
24
+ const packageManager = detectPackageManager();
25
+
21
26
  // Check Flow upgrade
22
- if (await UpgradeManager.isUpgradeAvailable()) {
27
+ if (updates.flowUpdate && updates.flowVersion) {
28
+ const upgradeCmd = getUpgradeCommand('@sylphx/flow', packageManager);
23
29
  console.log(
24
30
  chalk.yellow(
25
- `📦 Sylphx Flow update available: ${state.version} → ${state.latestVersion}\n`
31
+ `📦 Sylphx Flow update available: ${updates.flowVersion.current} → ${updates.flowVersion.latest}`
26
32
  )
27
33
  );
28
- const { default: inquirer } = await import('inquirer');
29
- const { upgrade } = await inquirer.prompt([
30
- {
31
- type: 'confirm',
32
- name: 'upgrade',
33
- message: 'Upgrade Sylphx Flow now?',
34
- default: true,
35
- },
36
- ]);
37
- if (upgrade) {
38
- options.upgrade = true;
39
- }
34
+ console.log(chalk.dim(` Quick upgrade: ${chalk.cyan('sylphx-flow upgrade --auto')}`));
35
+ console.log(chalk.dim(` Or run: ${chalk.cyan(upgradeCmd)}\n`));
40
36
  }
41
37
 
42
- // Check target upgrade (if target exists and outdated)
43
- if (state.target && state.targetVersion && state.targetLatestVersion &&
44
- state.targetVersion !== state.targetLatestVersion) {
45
- // Simple version comparison
46
- const isOutdated = compareVersions(state.targetVersion, state.targetLatestVersion) < 0;
47
-
48
- if (isOutdated) {
49
- console.log(
50
- chalk.yellow(
51
- `📦 ${state.target} update available: ${state.targetVersion} → ${state.targetLatestVersion}\n`
52
- )
53
- );
54
- const { default: inquirer } = await import('inquirer');
55
- const { upgradeTarget } = await inquirer.prompt([
56
- {
57
- type: 'confirm',
58
- name: 'upgradeTarget',
59
- message: `Upgrade ${state.target} now?`,
60
- default: true,
61
- },
62
- ]);
63
- if (upgradeTarget) {
64
- options.upgradeTarget = true;
65
- }
66
- }
38
+ // Check target upgrade
39
+ if (updates.targetUpdate && updates.targetVersion) {
40
+ console.log(
41
+ chalk.yellow(
42
+ `📦 Target update available: ${updates.targetVersion.current} ${updates.targetVersion.latest}`
43
+ )
44
+ );
45
+ console.log(chalk.dim(` Run: ${chalk.cyan('sylphx-flow upgrade --target --auto')}\n`));
67
46
  }
68
47
  }
69
48
 
70
- /**
71
- * Compare two version strings
72
- */
73
- function compareVersions(v1: string, v2: string): number {
74
- const parts1 = v1.split('.').map(Number);
75
- const parts2 = v2.split('.').map(Number);
76
-
77
- for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
78
- const p1 = parts1[i] || 0;
79
- const p2 = parts2[i] || 0;
80
- if (p1 !== p2) {
81
- return p1 - p2;
82
- }
83
- }
84
- return 0;
85
- }
86
49
 
87
50
  /**
88
51
  * Step 2: Check component integrity and prompt for repair
@@ -5,14 +5,20 @@ import { targetManager } from '../core/target-manager.js';
5
5
  import { CLIError } from '../utils/error-handler.js';
6
6
  import { getAgentsDir } from '../utils/config/paths.js';
7
7
 
8
- export async function loadAgentContent(agentName: string, agentFilePath?: string): Promise<string> {
8
+ export async function loadAgentContent(
9
+ agentName: string,
10
+ agentFilePath?: string,
11
+ enabledRules?: string[],
12
+ enabledOutputStyles?: string[]
13
+ ): Promise<string> {
9
14
  const { enhanceAgentContent } = await import('../utils/agent-enhancer.js');
10
15
 
11
16
  try {
12
17
  // If specific file path provided, load from there
13
18
  if (agentFilePath) {
14
19
  const content = await fs.readFile(path.resolve(agentFilePath), 'utf-8');
15
- return content;
20
+ // Enhance with enabled rules and styles
21
+ return await enhanceAgentContent(content, enabledRules, enabledOutputStyles);
16
22
  }
17
23
 
18
24
  // First try to load from .claude/agents/ directory (processed agents with rules and styles)
@@ -27,16 +33,16 @@ export async function loadAgentContent(agentName: string, agentFilePath?: string
27
33
 
28
34
  try {
29
35
  const content = await fs.readFile(localAgentPath, 'utf-8');
30
- // Enhance user-defined agents with rules and styles
31
- return await enhanceAgentContent(content);
36
+ // Enhance user-defined agents with enabled rules and styles
37
+ return await enhanceAgentContent(content, enabledRules, enabledOutputStyles);
32
38
  } catch (_error2) {
33
39
  // Try to load from the package's agents directory
34
40
  const packageAgentsDir = getAgentsDir();
35
41
  const packageAgentPath = path.join(packageAgentsDir, `${agentName}.md`);
36
42
 
37
43
  const content = await fs.readFile(packageAgentPath, 'utf-8');
38
- // Enhance package agents with rules and styles
39
- return await enhanceAgentContent(content);
44
+ // Enhance package agents with enabled rules and styles
45
+ return await enhanceAgentContent(content, enabledRules, enabledOutputStyles);
40
46
  }
41
47
  }
42
48
  } catch (_error) {