@sylphx/flow 1.8.2 → 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.
- package/CHANGELOG.md +59 -0
- package/UPGRADE.md +140 -0
- package/package.json +2 -1
- package/src/commands/flow/execute-v2.ts +278 -0
- package/src/commands/flow/execute.ts +1 -18
- package/src/commands/flow/types.ts +3 -2
- package/src/commands/flow-command.ts +32 -69
- package/src/commands/flow-orchestrator.ts +18 -55
- package/src/commands/run-command.ts +12 -6
- package/src/commands/settings-command.ts +529 -0
- package/src/core/attach-manager.ts +482 -0
- package/src/core/backup-manager.ts +308 -0
- package/src/core/cleanup-handler.ts +166 -0
- package/src/core/flow-executor.ts +323 -0
- package/src/core/git-stash-manager.ts +133 -0
- package/src/core/project-manager.ts +274 -0
- package/src/core/secrets-manager.ts +229 -0
- package/src/core/session-manager.ts +268 -0
- package/src/core/template-loader.ts +189 -0
- package/src/core/upgrade-manager.ts +79 -47
- package/src/index.ts +13 -27
- package/src/services/first-run-setup.ts +220 -0
- package/src/services/global-config.ts +337 -0
- package/src/utils/__tests__/package-manager-detector.test.ts +163 -0
- package/src/utils/agent-enhancer.ts +40 -22
- package/src/utils/errors.ts +9 -0
- package/src/utils/package-manager-detector.ts +139 -0
|
@@ -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
|
-
*
|
|
18
|
+
* Flow command (simplified for attach mode)
|
|
19
19
|
*/
|
|
20
20
|
export const flowCommand = new Command('flow')
|
|
21
|
-
.description('
|
|
22
|
-
|
|
23
|
-
//
|
|
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 -
|
|
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('
|
|
43
|
+
.description('[DEPRECATED] No longer needed - Flow uses automatic attach mode')
|
|
71
44
|
.action(async () => {
|
|
72
|
-
console.log(chalk.yellow('
|
|
73
|
-
console.log(chalk.
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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('📦
|
|
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('✓
|
|
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('
|
|
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('\
|
|
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━
|
|
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━
|
|
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✓
|
|
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 (
|
|
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: ${
|
|
31
|
+
`📦 Sylphx Flow update available: ${updates.flowVersion.current} → ${updates.flowVersion.latest}`
|
|
26
32
|
)
|
|
27
33
|
);
|
|
28
|
-
|
|
29
|
-
|
|
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
|
|
43
|
-
if (
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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(
|
|
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
|
-
|
|
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) {
|