@sylphx/flow 1.0.5 → 1.1.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 +46 -0
- package/assets/agents/coder.md +162 -0
- package/assets/agents/orchestrator.md +416 -0
- package/assets/agents/reviewer.md +192 -0
- package/assets/agents/writer.md +364 -0
- package/assets/icons/flow-notification-icon.png +0 -0
- package/assets/icons/flow-notification-icon.svg +17 -0
- package/assets/knowledge/data/sql.md +216 -0
- package/assets/knowledge/guides/saas-template.md +85 -0
- package/assets/knowledge/guides/system-prompt.md +344 -0
- package/assets/knowledge/guides/tech-stack.md +92 -0
- package/assets/knowledge/guides/ui-ux.md +44 -0
- package/assets/knowledge/stacks/nextjs-app.md +165 -0
- package/assets/knowledge/stacks/node-api.md +220 -0
- package/assets/knowledge/stacks/react-app.md +232 -0
- package/assets/knowledge/universal/deployment.md +109 -0
- package/assets/knowledge/universal/performance.md +121 -0
- package/assets/knowledge/universal/security.md +79 -0
- package/assets/knowledge/universal/testing.md +111 -0
- package/assets/output-styles/silent.md +23 -0
- package/assets/rules/code-standards.md +346 -0
- package/assets/rules/core.md +189 -0
- package/assets/slash-commands/commit.md +23 -0
- package/assets/slash-commands/context.md +112 -0
- package/assets/slash-commands/explain.md +35 -0
- package/assets/slash-commands/review.md +39 -0
- package/assets/slash-commands/test.md +30 -0
- package/package.json +4 -2
- package/src/services/smart-config-service.ts +15 -131
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Review code for quality, security, and best practices
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Code Review
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
$ARGUMENTS
|
|
10
|
+
|
|
11
|
+
## Your Task
|
|
12
|
+
|
|
13
|
+
Review the code above (or at the specified location) and provide feedback on:
|
|
14
|
+
|
|
15
|
+
1. **Code Quality**
|
|
16
|
+
- Readability and maintainability
|
|
17
|
+
- Code organization and structure
|
|
18
|
+
- Naming conventions
|
|
19
|
+
- Comments and documentation
|
|
20
|
+
|
|
21
|
+
2. **Security**
|
|
22
|
+
- Potential vulnerabilities
|
|
23
|
+
- Input validation
|
|
24
|
+
- Authentication/authorization issues
|
|
25
|
+
- Data exposure risks
|
|
26
|
+
|
|
27
|
+
3. **Performance**
|
|
28
|
+
- Algorithmic efficiency
|
|
29
|
+
- Resource usage
|
|
30
|
+
- Potential bottlenecks
|
|
31
|
+
- Scalability concerns
|
|
32
|
+
|
|
33
|
+
4. **Best Practices**
|
|
34
|
+
- Language-specific idioms
|
|
35
|
+
- Design patterns
|
|
36
|
+
- Error handling
|
|
37
|
+
- Testing coverage
|
|
38
|
+
|
|
39
|
+
Provide specific, actionable suggestions for improvement.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Write comprehensive tests for code
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Write Tests
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
$ARGUMENTS
|
|
10
|
+
|
|
11
|
+
## Your Task
|
|
12
|
+
|
|
13
|
+
Write comprehensive tests for the code above (or at the specified location) that include:
|
|
14
|
+
|
|
15
|
+
1. **Unit Tests**
|
|
16
|
+
- Test individual functions/methods
|
|
17
|
+
- Cover edge cases and boundary conditions
|
|
18
|
+
- Test error handling
|
|
19
|
+
|
|
20
|
+
2. **Integration Tests** (if applicable)
|
|
21
|
+
- Test component interactions
|
|
22
|
+
- Test with realistic data
|
|
23
|
+
|
|
24
|
+
3. **Test Coverage**
|
|
25
|
+
- Aim for high coverage of critical paths
|
|
26
|
+
- Include positive and negative test cases
|
|
27
|
+
- Test validation and error conditions
|
|
28
|
+
|
|
29
|
+
Use the project's existing testing framework and follow its conventions.
|
|
30
|
+
Ensure tests are readable, maintainable, and properly documented.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sylphx/flow",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "AI-powered development workflow automation with autonomous loop mode and smart configuration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"start": "bun src/index.ts",
|
|
15
15
|
"test": "vitest run",
|
|
16
16
|
"test:watch": "vitest",
|
|
17
|
-
"type-check": "tsc --noEmit"
|
|
17
|
+
"type-check": "tsc --noEmit",
|
|
18
|
+
"prepublishOnly": "rm -rf assets && cp -r ../../assets assets"
|
|
18
19
|
},
|
|
19
20
|
"dependencies": {
|
|
20
21
|
"commander": "^14.0.2",
|
|
@@ -38,6 +39,7 @@
|
|
|
38
39
|
},
|
|
39
40
|
"files": [
|
|
40
41
|
"src",
|
|
42
|
+
"assets",
|
|
41
43
|
"README.md",
|
|
42
44
|
"CHANGELOG.md",
|
|
43
45
|
"LOOP_MODE.md",
|
|
@@ -79,7 +79,7 @@ export class SmartConfigService {
|
|
|
79
79
|
});
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
// Mark setup as completed (
|
|
82
|
+
// Mark setup as completed (only save API keys, no defaults)
|
|
83
83
|
await ConfigService.saveHomeSettings({ hasCompletedSetup: true });
|
|
84
84
|
console.log(chalk.green('\n✓ Setup complete!\n'));
|
|
85
85
|
}
|
|
@@ -113,99 +113,14 @@ export class SmartConfigService {
|
|
|
113
113
|
await ConfigService.saveHomeSettings({ apiKeys: existingApiKeys });
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
-
/**
|
|
117
|
-
* Setup default preferences
|
|
118
|
-
*/
|
|
119
|
-
private static async setupDefaultPreferences(): Promise<void> {
|
|
120
|
-
console.log(chalk.cyan('⚙️ Setup Default Preferences\n'));
|
|
121
|
-
|
|
122
|
-
const userSettings = await ConfigService.loadHomeSettings();
|
|
123
|
-
const availableProviders = ConfigService.getAvailableProviders(userSettings);
|
|
124
|
-
|
|
125
|
-
if (availableProviders.length === 0) {
|
|
126
|
-
console.log(chalk.yellow('⚠ No API keys configured yet. Skipping preferences setup.'));
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
const { setupDefaults } = await inquirer.prompt([
|
|
131
|
-
{
|
|
132
|
-
type: 'confirm',
|
|
133
|
-
name: 'setupDefaults',
|
|
134
|
-
message: 'Set up default preferences?',
|
|
135
|
-
default: true,
|
|
136
|
-
},
|
|
137
|
-
]);
|
|
138
|
-
|
|
139
|
-
if (!setupDefaults) {
|
|
140
|
-
console.log(chalk.dim('Skipping preferences setup.'));
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// Select default provider
|
|
145
|
-
if (availableProviders.length > 1) {
|
|
146
|
-
const { defaultProvider } = await inquirer.prompt([
|
|
147
|
-
{
|
|
148
|
-
type: 'list',
|
|
149
|
-
name: 'defaultProvider',
|
|
150
|
-
message: 'Select default provider:',
|
|
151
|
-
choices: availableProviders.map(p => ({
|
|
152
|
-
name: p.charAt(0).toUpperCase() + p.slice(1),
|
|
153
|
-
value: p,
|
|
154
|
-
})),
|
|
155
|
-
default: userSettings.defaultProvider || availableProviders[0],
|
|
156
|
-
},
|
|
157
|
-
]);
|
|
158
|
-
|
|
159
|
-
userSettings.defaultProvider = defaultProvider;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// Set default agent (will use dynamic loading)
|
|
163
|
-
const { useDefaultAgent } = await inquirer.prompt([
|
|
164
|
-
{
|
|
165
|
-
type: 'confirm',
|
|
166
|
-
name: 'useDefaultAgent',
|
|
167
|
-
message: 'Set default agent?',
|
|
168
|
-
default: true,
|
|
169
|
-
},
|
|
170
|
-
]);
|
|
171
|
-
|
|
172
|
-
if (useDefaultAgent) {
|
|
173
|
-
try {
|
|
174
|
-
const agents = await loadAllAgents(process.cwd());
|
|
175
|
-
if (agents.length > 0) {
|
|
176
|
-
const { defaultAgent } = await inquirer.prompt([
|
|
177
|
-
{
|
|
178
|
-
type: 'list',
|
|
179
|
-
name: 'defaultAgent',
|
|
180
|
-
message: 'Select default agent:',
|
|
181
|
-
choices: agents.map(a => ({
|
|
182
|
-
name: a.metadata.name || a.id,
|
|
183
|
-
value: a.id,
|
|
184
|
-
})),
|
|
185
|
-
default: userSettings.defaultAgent || (agents.find(a => a.id === 'coder')?.id || agents[0].id),
|
|
186
|
-
},
|
|
187
|
-
]);
|
|
188
|
-
|
|
189
|
-
userSettings.defaultAgent = defaultAgent;
|
|
190
|
-
}
|
|
191
|
-
} catch (error) {
|
|
192
|
-
console.log(chalk.yellow('⚠ Could not load agents, using "coder" as default'));
|
|
193
|
-
userSettings.defaultAgent = 'coder';
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
await ConfigService.saveHomeSettings(userSettings);
|
|
198
|
-
console.log(chalk.green('✓ Default preferences saved'));
|
|
199
|
-
}
|
|
200
116
|
|
|
201
117
|
/**
|
|
202
118
|
* Runtime selection - choose provider and agent for this run
|
|
203
119
|
*
|
|
204
|
-
* DESIGN PRINCIPLE:
|
|
205
|
-
* - Has
|
|
206
|
-
* - No
|
|
207
|
-
* -
|
|
208
|
-
* - Explicit option (--provider/--agent) → Use specified value
|
|
120
|
+
* DESIGN PRINCIPLE: Always Ask (Simple & Explicit)
|
|
121
|
+
* - Has args (--provider/--agent) → Use them directly
|
|
122
|
+
* - No args → Always prompt user
|
|
123
|
+
* - Never save runtime choices as defaults
|
|
209
124
|
*/
|
|
210
125
|
static async selectRuntimeChoices(options: SmartConfigOptions): Promise<RuntimeChoices> {
|
|
211
126
|
const config = await ConfigService.loadConfiguration();
|
|
@@ -213,42 +128,22 @@ export class SmartConfigService {
|
|
|
213
128
|
|
|
214
129
|
// Handle provider selection
|
|
215
130
|
if (options.provider) {
|
|
216
|
-
//
|
|
131
|
+
// Explicit option provided via args
|
|
217
132
|
choices.provider = options.provider;
|
|
218
|
-
} else if (options.selectProvider) {
|
|
219
|
-
// 2. Force selection (override defaults)
|
|
220
|
-
choices.provider = await this.selectProvider(config.user);
|
|
221
|
-
} else if (config.user.defaultProvider) {
|
|
222
|
-
// 3. Use saved default (SMART DEFAULT - no prompt needed)
|
|
223
|
-
choices.provider = config.user.defaultProvider;
|
|
224
|
-
console.log(chalk.dim(` ✓ Provider: ${choices.provider}`));
|
|
225
133
|
} else {
|
|
226
|
-
//
|
|
134
|
+
// Always prompt
|
|
227
135
|
choices.provider = await this.selectProvider(config.user);
|
|
228
136
|
}
|
|
229
137
|
|
|
230
138
|
// Handle agent selection
|
|
231
139
|
if (options.agent) {
|
|
232
|
-
//
|
|
140
|
+
// Explicit option provided via args
|
|
233
141
|
choices.agent = options.agent;
|
|
234
|
-
} else if (options.selectAgent) {
|
|
235
|
-
// 2. Force selection (override defaults)
|
|
236
|
-
choices.agent = await this.selectAgent(config.user.defaultAgent);
|
|
237
|
-
} else if (config.user.defaultAgent) {
|
|
238
|
-
// 3. Use saved default (SMART DEFAULT - no prompt needed)
|
|
239
|
-
choices.agent = config.user.defaultAgent;
|
|
240
|
-
console.log(chalk.dim(` ✓ Agent: ${choices.agent}`));
|
|
241
142
|
} else {
|
|
242
|
-
//
|
|
243
|
-
choices.agent = await this.selectAgent(
|
|
143
|
+
// Always prompt
|
|
144
|
+
choices.agent = await this.selectAgent();
|
|
244
145
|
}
|
|
245
146
|
|
|
246
|
-
// Save choices for next time
|
|
247
|
-
await ConfigService.saveHomeSettings({
|
|
248
|
-
defaultProvider: choices.provider,
|
|
249
|
-
defaultAgent: choices.agent,
|
|
250
|
-
});
|
|
251
|
-
|
|
252
147
|
return choices;
|
|
253
148
|
}
|
|
254
149
|
|
|
@@ -265,22 +160,16 @@ export class SmartConfigService {
|
|
|
265
160
|
{ id: 'z.ai', name: 'Z.ai (Recommended)', hasKey: !!apiKeys['z.ai'] },
|
|
266
161
|
];
|
|
267
162
|
|
|
268
|
-
// Show last used provider hint
|
|
269
|
-
const lastUsed = userSettings.defaultProvider;
|
|
270
|
-
const message = lastUsed
|
|
271
|
-
? `Select provider (last used: ${lastUsed}):`
|
|
272
|
-
: 'Select provider:';
|
|
273
|
-
|
|
274
163
|
const { provider } = await inquirer.prompt([
|
|
275
164
|
{
|
|
276
165
|
type: 'list',
|
|
277
166
|
name: 'provider',
|
|
278
|
-
message,
|
|
167
|
+
message: 'Select provider:',
|
|
279
168
|
choices: allProviders.map(p => ({
|
|
280
169
|
name: p.hasKey ? p.name : `${p.name} (Need API key)`,
|
|
281
170
|
value: p.id,
|
|
282
171
|
})),
|
|
283
|
-
default:
|
|
172
|
+
default: 'default',
|
|
284
173
|
},
|
|
285
174
|
]);
|
|
286
175
|
|
|
@@ -309,7 +198,7 @@ export class SmartConfigService {
|
|
|
309
198
|
/**
|
|
310
199
|
* Select agent for this run
|
|
311
200
|
*/
|
|
312
|
-
private static async selectAgent(
|
|
201
|
+
private static async selectAgent(): Promise<string> {
|
|
313
202
|
try {
|
|
314
203
|
const agents = await loadAllAgents(process.cwd());
|
|
315
204
|
|
|
@@ -318,21 +207,16 @@ export class SmartConfigService {
|
|
|
318
207
|
return 'coder';
|
|
319
208
|
}
|
|
320
209
|
|
|
321
|
-
// Build message with last used hint
|
|
322
|
-
const message = lastUsed
|
|
323
|
-
? `Select agent (last used: ${lastUsed}):`
|
|
324
|
-
: 'Select agent:';
|
|
325
|
-
|
|
326
210
|
const { agent } = await inquirer.prompt([
|
|
327
211
|
{
|
|
328
212
|
type: 'list',
|
|
329
213
|
name: 'agent',
|
|
330
|
-
message,
|
|
214
|
+
message: 'Select agent:',
|
|
331
215
|
choices: agents.map(a => ({
|
|
332
216
|
name: a.metadata.name || a.id,
|
|
333
217
|
value: a.id,
|
|
334
218
|
})),
|
|
335
|
-
default:
|
|
219
|
+
default: agents.find(a => a.id === 'coder')?.id || agents[0].id,
|
|
336
220
|
},
|
|
337
221
|
]);
|
|
338
222
|
|