@sylphx/flow 1.0.3 → 1.0.5

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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # @sylphx/flow
2
2
 
3
+ ## 1.0.5
4
+
5
+ ### Patch Changes
6
+
7
+ - Fix Claude Code component detection - rules and output styles are included in agent files
8
+
9
+ ## 1.0.4
10
+
11
+ ### Patch Changes
12
+
13
+ - Fix false "missing components" warning by checking if directories contain files
14
+
3
15
  ## 1.0.3
4
16
 
5
17
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sylphx/flow",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "AI-powered development workflow automation with autonomous loop mode and smart configuration",
5
5
  "type": "module",
6
6
  "bin": {
@@ -99,22 +99,29 @@ export async function checkComponentIntegrity(
99
99
 
100
100
  // Find missing components (target-aware)
101
101
  const missing: string[] = [];
102
+
103
+ // Agents are always required
102
104
  if (!state.components.agents.installed) missing.push('agents');
103
- if (!state.components.rules.installed) missing.push('rules');
104
105
 
105
- // Only check hooks for Claude Code (OpenCode doesn't have separate hooks)
106
- if (state.target !== 'opencode' && !state.components.hooks.installed) {
107
- missing.push('hooks');
106
+ // For OpenCode: check rules (separate AGENTS.md file)
107
+ // For Claude Code: rules are included in agent files, so skip this check
108
+ if (state.target === 'opencode' && !state.components.rules.installed) {
109
+ missing.push('rules');
108
110
  }
109
111
 
110
- if (!state.components.mcp.installed) missing.push('mcp');
112
+ // Hooks are optional - don't check
113
+ // Claude Code can have hooks in .claude/hooks/*.js but they're optional
114
+ // OpenCode doesn't have separate hooks
111
115
 
112
- // Only check output styles for Claude Code (OpenCode uses AGENTS.md)
113
- if (state.target !== 'opencode' && !state.components.outputStyles.installed) {
114
- missing.push('output styles');
115
- }
116
+ // MCP is optional now - many users don't use MCP
117
+ // if (!state.components.mcp.installed) missing.push('mcp');
118
+
119
+ // Output styles:
120
+ // - Claude Code: included in agent files, so skip check
121
+ // - OpenCode: included in AGENTS.md, so skip check
116
122
 
117
- if (!state.components.slashCommands.installed) missing.push('slash commands');
123
+ // Slash commands are optional
124
+ // if (!state.components.slashCommands.installed) missing.push('slash commands');
118
125
 
119
126
  // If no missing components, we're good
120
127
  if (missing.length === 0) return;
@@ -91,9 +91,18 @@ export class StateDetector {
91
91
  } else {
92
92
  // Claude Code (default)
93
93
  await this.checkComponent('agents', '.claude/agents', '*.md', state);
94
- await this.checkComponent('rules', '.claude/rules', '*.md', state);
94
+
95
+ // Claude Code includes rules and output styles in agent files
96
+ // So we mark them as installed if agents are installed
97
+ state.components.rules.installed = state.components.agents.installed;
98
+ state.components.rules.count = state.components.agents.count;
99
+
100
+ state.components.outputStyles.installed = state.components.agents.installed;
101
+
102
+ // Check hooks (optional for Claude Code)
95
103
  await this.checkComponent('hooks', '.claude/hooks', '*.js', state);
96
- await this.checkComponent('outputStyles', '.claude/output-styles', '*.md', state);
104
+
105
+ // Check slash commands
97
106
  await this.checkComponent('slashCommands', '.claude/commands', '*.md', state);
98
107
  }
99
108
 
@@ -203,24 +212,28 @@ export class StateDetector {
203
212
  const fullPath = path.join(this.projectPath, componentPath);
204
213
  const exists = await fs.access(fullPath).then(() => true).catch(() => false);
205
214
 
206
- state.components[componentName].installed = exists;
215
+ if (!exists) {
216
+ state.components[componentName].installed = false;
217
+ return;
218
+ }
207
219
 
208
- if (exists) {
209
- // 计算文件数量
210
- const files = await fs.readdir(fullPath).catch(() => []);
211
- const count = pattern === '*.js' ? files.filter(f => f.endsWith('.js')).length :
212
- pattern === '*.md' ? files.filter(f => f.endsWith('.md')).length : files.length;
220
+ // 计算文件数量
221
+ const files = await fs.readdir(fullPath).catch(() => []);
222
+ const count = pattern === '*.js' ? files.filter(f => f.endsWith('.js')).length :
223
+ pattern === '*.md' ? files.filter(f => f.endsWith('.md')).length : files.length;
213
224
 
214
- if (componentName === 'agents' || componentName === 'slashCommands' || componentName === 'rules') {
215
- state.components[componentName].count = count;
216
- }
225
+ // Component is only installed if it has files
226
+ state.components[componentName].installed = count > 0;
217
227
 
218
- // 这里可以读取版本信息(如果保存了的话)
219
- const versionPath = path.join(fullPath, '.version');
220
- const versionExists = await fs.access(versionPath).then(() => true).catch(() => false);
221
- if (versionExists) {
222
- state.components[componentName].version = await fs.readFile(versionPath, 'utf-8');
223
- }
228
+ if (componentName === 'agents' || componentName === 'slashCommands' || componentName === 'rules') {
229
+ state.components[componentName].count = count;
230
+ }
231
+
232
+ // 这里可以读取版本信息(如果保存了的话)
233
+ const versionPath = path.join(fullPath, '.version');
234
+ const versionExists = await fs.access(versionPath).then(() => true).catch(() => false);
235
+ if (versionExists) {
236
+ state.components[componentName].version = await fs.readFile(versionPath, 'utf-8');
224
237
  }
225
238
  } catch {
226
239
  state.components[componentName].installed = false;