@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
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,64 @@
|
|
|
1
1
|
# @sylphx/flow
|
|
2
2
|
|
|
3
|
+
## 2.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- aaadcaa: Settings-based configuration and improved user experience
|
|
8
|
+
|
|
9
|
+
**New Features:**
|
|
10
|
+
|
|
11
|
+
- **Settings management**: Configure agents, rules, and output styles via `sylphx-flow settings`
|
|
12
|
+
- Select which agents are enabled
|
|
13
|
+
- Set default agent to use
|
|
14
|
+
- Enable/disable specific rules (core, code-standards, workspace)
|
|
15
|
+
- Enable/disable output styles (silent)
|
|
16
|
+
- **Settings-driven execution**: Flow respects your settings and only loads enabled components
|
|
17
|
+
- **Config files**: All settings stored in `~/.sylphx-flow/` (settings.json, flow-config.json, provider-config.json, mcp-config.json)
|
|
18
|
+
- **Git skip-worktree integration**: Flow automatically hides `.claude/` and `.opencode/` changes from git
|
|
19
|
+
- Uses `git update-index --skip-worktree` to hide Flow's temporary modifications
|
|
20
|
+
- Prevents LLM from seeing or committing Flow's settings changes
|
|
21
|
+
- Automatically restores git tracking after execution
|
|
22
|
+
- Works seamlessly with version-controlled settings
|
|
23
|
+
|
|
24
|
+
**Breaking Changes:**
|
|
25
|
+
|
|
26
|
+
- Removed `--quick` flag - no longer needed
|
|
27
|
+
- Removed first-run setup wizard - configs are created automatically with sensible defaults
|
|
28
|
+
- Agent loading now respects enabled rules and output styles from settings
|
|
29
|
+
|
|
30
|
+
**Improvements:**
|
|
31
|
+
|
|
32
|
+
- Config files are automatically initialized on first use with default values
|
|
33
|
+
- Provider selection happens inline when needed (if set to "ask-every-time")
|
|
34
|
+
- Fixed Ctrl+C handling to ensure settings are restored immediately
|
|
35
|
+
- Simplified CLI options - only `--merge` flag for attach strategy
|
|
36
|
+
- Default agent can be set in settings (falls back to 'coder' if not set)
|
|
37
|
+
|
|
38
|
+
**Ctrl+C Fix:**
|
|
39
|
+
When users press Ctrl+C during interactive prompts, the application now:
|
|
40
|
+
|
|
41
|
+
- Catches the cancellation gracefully
|
|
42
|
+
- Runs cleanup (restores backed-up settings)
|
|
43
|
+
- Shows a friendly cancellation message
|
|
44
|
+
- Exits cleanly
|
|
45
|
+
|
|
46
|
+
Previously, pressing Ctrl+C would exit immediately without restoring settings, requiring recovery on the next run.
|
|
47
|
+
|
|
48
|
+
### Minor Changes
|
|
49
|
+
|
|
50
|
+
- 9fa65d4: Add automatic upgrade detection with smart package manager support
|
|
51
|
+
|
|
52
|
+
- Auto-detect updates on startup with non-intrusive notifications
|
|
53
|
+
- Enhanced `upgrade` command with `--auto` flag for automatic installation
|
|
54
|
+
- Smart package manager detection (npm, bun, pnpm, yarn)
|
|
55
|
+
- Version checking against npm registry for both Flow and target platforms
|
|
56
|
+
- Package-manager-specific upgrade commands in notifications
|
|
57
|
+
- New UPGRADE.md documentation with package manager support
|
|
58
|
+
- Silent background checks that don't block execution
|
|
59
|
+
- Support for both interactive and automatic upgrade flows
|
|
60
|
+
- Comprehensive test coverage for package manager detection
|
|
61
|
+
|
|
3
62
|
## 1.8.2
|
|
4
63
|
|
|
5
64
|
### Patch Changes
|
package/UPGRADE.md
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Upgrade Guide
|
|
2
|
+
|
|
3
|
+
Sylphx Flow includes built-in upgrade detection and automatic update capabilities with **smart package manager detection**.
|
|
4
|
+
|
|
5
|
+
## Auto-Detection on Startup
|
|
6
|
+
|
|
7
|
+
Every time you run Sylphx Flow, it automatically checks for available updates in the background. If an update is available, you'll see a notification like:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
š¦ Sylphx Flow update available: 1.8.1 ā 1.9.0
|
|
11
|
+
Quick upgrade: sylphx-flow upgrade --auto
|
|
12
|
+
Or run: bun install -g @sylphx/flow@latest
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The upgrade command is automatically tailored to your detected package manager (npm, bun, pnpm, or yarn).
|
|
16
|
+
|
|
17
|
+
This check is non-intrusive and won't block your workflow. Use `--quick` mode to skip the check entirely.
|
|
18
|
+
|
|
19
|
+
## Manual Upgrade Check
|
|
20
|
+
|
|
21
|
+
Check for available updates without installing:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
sylphx-flow upgrade --check
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Upgrade Commands
|
|
28
|
+
|
|
29
|
+
### Upgrade Sylphx Flow
|
|
30
|
+
|
|
31
|
+
Upgrade to the latest version:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# Interactive upgrade (manual installation required)
|
|
35
|
+
sylphx-flow upgrade
|
|
36
|
+
|
|
37
|
+
# Automatic installation via npm
|
|
38
|
+
sylphx-flow upgrade --auto
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Upgrade Target Platform
|
|
42
|
+
|
|
43
|
+
Upgrade Claude Code or other target platforms:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# Interactive upgrade
|
|
47
|
+
sylphx-flow upgrade --target
|
|
48
|
+
|
|
49
|
+
# Automatic installation via npm
|
|
50
|
+
sylphx-flow upgrade --target --auto
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Combined Upgrade
|
|
54
|
+
|
|
55
|
+
Upgrade both Sylphx Flow and target platform:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
sylphx-flow upgrade --target --auto
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Options
|
|
62
|
+
|
|
63
|
+
- `--check` - Only check for updates, don't install
|
|
64
|
+
- `--auto` - Automatically install updates via npm (no manual steps)
|
|
65
|
+
- `--target` - Include target platform (Claude Code/OpenCode) upgrade
|
|
66
|
+
- `--verbose` - Show detailed installation output
|
|
67
|
+
|
|
68
|
+
## Package Manager Detection
|
|
69
|
+
|
|
70
|
+
Sylphx Flow automatically detects which package manager you're using:
|
|
71
|
+
|
|
72
|
+
1. **From Environment** (`npm_config_user_agent`): Most reliable when running as npm script
|
|
73
|
+
2. **From Lock Files**: Checks for `bun.lock`, `pnpm-lock.yaml`, `yarn.lock`, or `package-lock.json`
|
|
74
|
+
3. **Default**: Falls back to `npm` if no detection method works
|
|
75
|
+
|
|
76
|
+
**Priority Order**: bun > pnpm > yarn > npm
|
|
77
|
+
|
|
78
|
+
### Supported Package Managers
|
|
79
|
+
|
|
80
|
+
| Package Manager | Global Install Command |
|
|
81
|
+
|----------------|------------------------|
|
|
82
|
+
| npm | `npm install -g @sylphx/flow@latest` |
|
|
83
|
+
| bun | `bun install -g @sylphx/flow@latest` |
|
|
84
|
+
| pnpm | `pnpm install -g @sylphx/flow@latest` |
|
|
85
|
+
| yarn | `yarn global add @sylphx/flow@latest` |
|
|
86
|
+
|
|
87
|
+
## How It Works
|
|
88
|
+
|
|
89
|
+
1. **Version Detection**: Checks npm registry for latest published versions
|
|
90
|
+
2. **Comparison**: Compares installed version with latest available
|
|
91
|
+
3. **Package Manager Detection**: Automatically detects npm/bun/pnpm/yarn
|
|
92
|
+
4. **Notification**: Shows update availability with package-manager-specific command
|
|
93
|
+
5. **Installation**:
|
|
94
|
+
- Without `--auto`: Shows manual install command for your package manager
|
|
95
|
+
- With `--auto`: Runs the appropriate install command automatically
|
|
96
|
+
|
|
97
|
+
## Disabling Auto-Check
|
|
98
|
+
|
|
99
|
+
Use `--quick` mode to skip automatic update checks:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
sylphx-flow --quick "your prompt here"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Troubleshooting
|
|
106
|
+
|
|
107
|
+
### Auto-Install Fails
|
|
108
|
+
|
|
109
|
+
If `--auto` installation fails, the error message will show the exact command to run manually. The command is tailored to your package manager:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# Example for bun users
|
|
113
|
+
bun install -g @sylphx/flow@latest
|
|
114
|
+
|
|
115
|
+
# Example for npm users
|
|
116
|
+
npm install -g @sylphx/flow@latest
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Version Mismatch
|
|
120
|
+
|
|
121
|
+
If you see version mismatches after upgrade, try:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# Re-sync components with latest templates
|
|
125
|
+
sylphx-flow --sync
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Offline Mode
|
|
129
|
+
|
|
130
|
+
Update checks require internet connection. If offline, checks will fail silently and won't block execution.
|
|
131
|
+
|
|
132
|
+
## Version Compatibility
|
|
133
|
+
|
|
134
|
+
Sylphx Flow follows semantic versioning:
|
|
135
|
+
|
|
136
|
+
- **Patch** (1.8.x): Bug fixes, safe to upgrade
|
|
137
|
+
- **Minor** (1.x.0): New features, backward compatible
|
|
138
|
+
- **Major** (x.0.0): Breaking changes, check migration guide
|
|
139
|
+
|
|
140
|
+
Always check CHANGELOG.md for breaking changes before upgrading major versions.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sylphx/flow",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "AI-powered development workflow automation with autonomous loop mode and smart configuration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"README.md",
|
|
44
44
|
"CHANGELOG.md",
|
|
45
45
|
"LOOP_MODE.md",
|
|
46
|
+
"UPGRADE.md",
|
|
46
47
|
"package.json"
|
|
47
48
|
],
|
|
48
49
|
"keywords": [
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Execution Logic for Flow Command (V2 - Attach Mode)
|
|
3
|
+
* New execution flow with attach-mode lifecycle
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
import inquirer from 'inquirer';
|
|
8
|
+
import { FlowExecutor } from '../../core/flow-executor.js';
|
|
9
|
+
import { targetManager } from '../../core/target-manager.js';
|
|
10
|
+
import { UpgradeManager } from '../../core/upgrade-manager.js';
|
|
11
|
+
import { showWelcome } from '../../utils/display/banner.js';
|
|
12
|
+
import { loadAgentContent, extractAgentInstructions } from '../run-command.js';
|
|
13
|
+
import { CLIError } from '../../utils/error-handler.js';
|
|
14
|
+
import type { RunCommandOptions } from '../../types.js';
|
|
15
|
+
import type { FlowOptions } from './types.js';
|
|
16
|
+
import { resolvePrompt } from './prompt.js';
|
|
17
|
+
import { GlobalConfigService } from '../../services/global-config.js';
|
|
18
|
+
import { UserCancelledError } from '../../utils/errors.js';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Select and configure provider for Claude Code
|
|
22
|
+
*/
|
|
23
|
+
async function selectProvider(
|
|
24
|
+
configService: GlobalConfigService
|
|
25
|
+
): Promise<void> {
|
|
26
|
+
try {
|
|
27
|
+
const providerConfig = await configService.loadProviderConfig();
|
|
28
|
+
const defaultProvider = providerConfig.claudeCode.defaultProvider;
|
|
29
|
+
|
|
30
|
+
// If not "ask-every-time", use the default provider
|
|
31
|
+
if (defaultProvider !== 'ask-every-time') {
|
|
32
|
+
// Configure environment variables for the selected provider
|
|
33
|
+
if (defaultProvider === 'kimi' || defaultProvider === 'zai') {
|
|
34
|
+
const provider = providerConfig.claudeCode.providers[defaultProvider];
|
|
35
|
+
if (provider?.apiKey) {
|
|
36
|
+
if (defaultProvider === 'kimi') {
|
|
37
|
+
process.env.ANTHROPIC_BASE_URL = 'https://api.moonshot.cn/v1';
|
|
38
|
+
process.env.ANTHROPIC_API_KEY = provider.apiKey;
|
|
39
|
+
} else if (defaultProvider === 'zai') {
|
|
40
|
+
process.env.ANTHROPIC_BASE_URL = 'https://api.z.ai/v1';
|
|
41
|
+
process.env.ANTHROPIC_API_KEY = provider.apiKey;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Ask user which provider to use for this session
|
|
49
|
+
const { selectedProvider } = await inquirer.prompt([
|
|
50
|
+
{
|
|
51
|
+
type: 'list',
|
|
52
|
+
name: 'selectedProvider',
|
|
53
|
+
message: 'Select provider for this session:',
|
|
54
|
+
choices: [
|
|
55
|
+
{ name: 'Default (Claude Code built-in)', value: 'default' },
|
|
56
|
+
{ name: 'Kimi', value: 'kimi' },
|
|
57
|
+
{ name: 'Z.ai', value: 'zai' },
|
|
58
|
+
],
|
|
59
|
+
default: 'default',
|
|
60
|
+
},
|
|
61
|
+
]);
|
|
62
|
+
|
|
63
|
+
// Configure environment variables based on selection
|
|
64
|
+
if (selectedProvider === 'kimi' || selectedProvider === 'zai') {
|
|
65
|
+
const provider = providerConfig.claudeCode.providers[selectedProvider];
|
|
66
|
+
|
|
67
|
+
if (!provider?.apiKey) {
|
|
68
|
+
console.log(chalk.yellow('ā API key not configured. Use: sylphx-flow settings\n'));
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (selectedProvider === 'kimi') {
|
|
73
|
+
process.env.ANTHROPIC_BASE_URL = 'https://api.moonshot.cn/v1';
|
|
74
|
+
process.env.ANTHROPIC_API_KEY = provider.apiKey;
|
|
75
|
+
console.log(chalk.green('ā Using Kimi provider\n'));
|
|
76
|
+
} else if (selectedProvider === 'zai') {
|
|
77
|
+
process.env.ANTHROPIC_BASE_URL = 'https://api.z.ai/v1';
|
|
78
|
+
process.env.ANTHROPIC_API_KEY = provider.apiKey;
|
|
79
|
+
console.log(chalk.green('ā Using Z.ai provider\n'));
|
|
80
|
+
}
|
|
81
|
+
} else {
|
|
82
|
+
console.log(chalk.green('ā Using default Claude Code provider\n'));
|
|
83
|
+
}
|
|
84
|
+
} catch (error: any) {
|
|
85
|
+
// Handle user cancellation (Ctrl+C)
|
|
86
|
+
if (error.name === 'ExitPromptError' || error.message?.includes('force closed')) {
|
|
87
|
+
throw new UserCancelledError('Provider selection cancelled');
|
|
88
|
+
}
|
|
89
|
+
throw error;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Execute command using target's executeCommand method
|
|
95
|
+
*/
|
|
96
|
+
async function executeTargetCommand(
|
|
97
|
+
targetId: string,
|
|
98
|
+
systemPrompt: string,
|
|
99
|
+
userPrompt: string,
|
|
100
|
+
options: RunCommandOptions
|
|
101
|
+
): Promise<void> {
|
|
102
|
+
const targetOption = targetManager.getTarget(targetId);
|
|
103
|
+
|
|
104
|
+
if (targetOption._tag === 'None') {
|
|
105
|
+
throw new CLIError(`Target not found: ${targetId}`, 'TARGET_NOT_FOUND');
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const target = targetOption.value;
|
|
109
|
+
|
|
110
|
+
if (!target.isImplemented || !target.executeCommand) {
|
|
111
|
+
throw new CLIError(
|
|
112
|
+
`Target '${targetId}' does not support command execution`,
|
|
113
|
+
'EXECUTION_NOT_SUPPORTED'
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return target.executeCommand(systemPrompt, userPrompt, options);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Main flow execution with attach mode (V2)
|
|
122
|
+
*/
|
|
123
|
+
export async function executeFlowV2(
|
|
124
|
+
prompt: string | undefined,
|
|
125
|
+
options: FlowOptions
|
|
126
|
+
): Promise<void> {
|
|
127
|
+
const projectPath = process.cwd();
|
|
128
|
+
|
|
129
|
+
// Show welcome banner
|
|
130
|
+
showWelcome();
|
|
131
|
+
|
|
132
|
+
// Mode info
|
|
133
|
+
if (options.merge) {
|
|
134
|
+
console.log(chalk.cyan('š Merge mode: Flow settings will be merged with your existing settings'));
|
|
135
|
+
console.log(chalk.dim(' Settings will be restored after execution\n'));
|
|
136
|
+
} else {
|
|
137
|
+
console.log(chalk.yellow('š Replace mode (default): All settings will use Flow configuration'));
|
|
138
|
+
console.log(chalk.dim(' Use --merge to keep your existing settings\n'));
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Initialize config service
|
|
142
|
+
const configService = new GlobalConfigService();
|
|
143
|
+
await configService.initialize();
|
|
144
|
+
|
|
145
|
+
// Create executor
|
|
146
|
+
const executor = new FlowExecutor();
|
|
147
|
+
const projectManager = executor.getProjectManager();
|
|
148
|
+
|
|
149
|
+
// Step 1: Check for upgrades (non-intrusive)
|
|
150
|
+
const upgradeManager = new UpgradeManager();
|
|
151
|
+
const updates = await upgradeManager.checkUpdates();
|
|
152
|
+
|
|
153
|
+
if (updates.flowUpdate || updates.targetUpdate) {
|
|
154
|
+
console.log(
|
|
155
|
+
chalk.yellow('š¦ Updates available! Run: sylphx-flow upgrade --auto\n')
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Step 2: Execute attach mode lifecycle
|
|
160
|
+
try {
|
|
161
|
+
// Attach Flow environment (backup ā attach ā register cleanup)
|
|
162
|
+
await executor.execute(projectPath, {
|
|
163
|
+
verbose: options.verbose,
|
|
164
|
+
skipBackup: false,
|
|
165
|
+
skipSecrets: false,
|
|
166
|
+
merge: options.merge || false,
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// Step 3: Detect target and load agent
|
|
170
|
+
const projectHash = projectManager.getProjectHash(projectPath);
|
|
171
|
+
const target = await projectManager.detectTarget(projectPath);
|
|
172
|
+
|
|
173
|
+
// Map target to targetManager's target IDs
|
|
174
|
+
const targetId = target === 'claude-code' ? 'claude-code' : 'opencode';
|
|
175
|
+
|
|
176
|
+
// Step 3.5: Provider selection (Claude Code only)
|
|
177
|
+
if (targetId === 'claude-code') {
|
|
178
|
+
await selectProvider(configService);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Step 3.6: Load Flow settings and determine agent to use
|
|
182
|
+
const settings = await configService.loadSettings();
|
|
183
|
+
const flowConfig = await configService.loadFlowConfig();
|
|
184
|
+
|
|
185
|
+
// Determine which agent to use (CLI option > settings default > 'coder')
|
|
186
|
+
const agent = options.agent || settings.defaultAgent || 'coder';
|
|
187
|
+
|
|
188
|
+
// Check if agent is enabled
|
|
189
|
+
if (!flowConfig.agents[agent]?.enabled) {
|
|
190
|
+
console.log(chalk.yellow(`ā ļø Agent '${agent}' is not enabled in settings`));
|
|
191
|
+
console.log(chalk.yellow(` Enable it with: sylphx-flow settings`));
|
|
192
|
+
console.log(chalk.yellow(` Using 'coder' agent instead\n`));
|
|
193
|
+
// Fallback to first enabled agent or coder
|
|
194
|
+
const enabledAgents = await configService.getEnabledAgents();
|
|
195
|
+
const fallbackAgent = enabledAgents.length > 0 ? enabledAgents[0] : 'coder';
|
|
196
|
+
options.agent = fallbackAgent;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
console.log(chalk.cyan(`š¤ Running agent: ${agent}\n`));
|
|
200
|
+
|
|
201
|
+
// Load enabled rules and output styles from config
|
|
202
|
+
const enabledRules = await configService.getEnabledRules();
|
|
203
|
+
const enabledOutputStyles = await configService.getEnabledOutputStyles();
|
|
204
|
+
|
|
205
|
+
console.log(chalk.dim(` Enabled rules: ${enabledRules.join(', ')}`));
|
|
206
|
+
console.log(chalk.dim(` Enabled output styles: ${enabledOutputStyles.join(', ')}\n`));
|
|
207
|
+
|
|
208
|
+
// Load agent content with only enabled rules and styles
|
|
209
|
+
const agentContent = await loadAgentContent(
|
|
210
|
+
agent,
|
|
211
|
+
options.agentFile,
|
|
212
|
+
enabledRules,
|
|
213
|
+
enabledOutputStyles
|
|
214
|
+
);
|
|
215
|
+
const agentInstructions = extractAgentInstructions(agentContent);
|
|
216
|
+
|
|
217
|
+
const systemPrompt = `AGENT INSTRUCTIONS:\n${agentInstructions}`;
|
|
218
|
+
|
|
219
|
+
const userPrompt = prompt?.trim() || '';
|
|
220
|
+
|
|
221
|
+
// Prepare run options
|
|
222
|
+
const runOptions: RunCommandOptions = {
|
|
223
|
+
target: targetId,
|
|
224
|
+
verbose: options.verbose || false,
|
|
225
|
+
dryRun: options.dryRun || false,
|
|
226
|
+
agent,
|
|
227
|
+
agentFile: options.agentFile,
|
|
228
|
+
prompt,
|
|
229
|
+
print: options.print,
|
|
230
|
+
continue: options.continue,
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
// Step 4: Execute command
|
|
234
|
+
await executeTargetCommand(targetId, systemPrompt, userPrompt, runOptions);
|
|
235
|
+
|
|
236
|
+
// Step 5: Cleanup (restore environment)
|
|
237
|
+
await executor.cleanup(projectPath);
|
|
238
|
+
|
|
239
|
+
console.log(chalk.green('ā Session complete\n'));
|
|
240
|
+
} catch (error) {
|
|
241
|
+
// Handle user cancellation gracefully
|
|
242
|
+
if (error instanceof UserCancelledError) {
|
|
243
|
+
console.log(chalk.yellow('\nā ļø Operation cancelled by user'));
|
|
244
|
+
try {
|
|
245
|
+
await executor.cleanup(projectPath);
|
|
246
|
+
console.log(chalk.green(' ā Settings restored\n'));
|
|
247
|
+
} catch (cleanupError) {
|
|
248
|
+
console.error(chalk.red(' ā Cleanup failed:'), cleanupError);
|
|
249
|
+
}
|
|
250
|
+
process.exit(0);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
console.error(chalk.red.bold('\nā Execution failed:'), error);
|
|
254
|
+
|
|
255
|
+
// Ensure cleanup even on error
|
|
256
|
+
try {
|
|
257
|
+
await executor.cleanup(projectPath);
|
|
258
|
+
} catch (cleanupError) {
|
|
259
|
+
console.error(chalk.red('ā Cleanup failed:'), cleanupError);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
throw error;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Main flow execution entry point
|
|
268
|
+
*/
|
|
269
|
+
export async function executeFlow(
|
|
270
|
+
prompt: string | undefined,
|
|
271
|
+
options: FlowOptions
|
|
272
|
+
): Promise<void> {
|
|
273
|
+
// Resolve prompt (handle file input)
|
|
274
|
+
const resolvedPrompt = await resolvePrompt(prompt);
|
|
275
|
+
|
|
276
|
+
// Use V2 attach mode execution
|
|
277
|
+
await executeFlowV2(resolvedPrompt, options);
|
|
278
|
+
}
|
|
@@ -124,28 +124,11 @@ export async function executeFlowOnce(prompt: string | undefined, options: FlowO
|
|
|
124
124
|
await showStatus(state);
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
-
// Step 1: Check for upgrades
|
|
127
|
+
// Step 1: Check for upgrades (non-intrusive notification)
|
|
128
128
|
if (!options.quick) {
|
|
129
129
|
await checkUpgrades(state, options);
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
// Step 1: Upgrade (if requested)
|
|
133
|
-
if (options.upgrade && state.outdated && state.latestVersion) {
|
|
134
|
-
console.log(chalk.cyan.bold('āāā š¦ Upgrading Flow\n'));
|
|
135
|
-
await upgradeManager.upgradeFlow(state);
|
|
136
|
-
console.log(chalk.green('ā Upgrade complete\n'));
|
|
137
|
-
// Re-detect after upgrade
|
|
138
|
-
state.version = state.latestVersion;
|
|
139
|
-
state.outdated = false;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// Step 2: Upgrade target (if requested)
|
|
143
|
-
if (options.upgradeTarget && state.target) {
|
|
144
|
-
console.log(chalk.cyan.bold(`āāā šÆ Upgrading ${state.target}\n`));
|
|
145
|
-
await upgradeManager.upgradeTarget(state);
|
|
146
|
-
console.log(chalk.green('ā Target upgrade complete\n'));
|
|
147
|
-
}
|
|
148
|
-
|
|
149
132
|
// Step 2.5: Check component integrity (only if we have valid state)
|
|
150
133
|
await checkComponentIntegrity(state, options);
|
|
151
134
|
|
|
@@ -26,14 +26,15 @@ export interface FlowOptions {
|
|
|
26
26
|
// Smart configuration options
|
|
27
27
|
selectProvider?: boolean;
|
|
28
28
|
selectAgent?: boolean;
|
|
29
|
-
useDefaults?: boolean;
|
|
30
29
|
provider?: string;
|
|
31
|
-
quick?: boolean;
|
|
32
30
|
|
|
33
31
|
// Execution modes
|
|
34
32
|
print?: boolean;
|
|
35
33
|
continue?: boolean;
|
|
36
34
|
|
|
35
|
+
// Attach strategy
|
|
36
|
+
merge?: boolean; // Merge with user settings instead of replacing (default: replace)
|
|
37
|
+
|
|
37
38
|
// Loop mode
|
|
38
39
|
loop?: number;
|
|
39
40
|
maxRuns?: number;
|