@sylphx/flow 1.4.10 → 1.4.12
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 +19 -0
- package/package.json +1 -1
- package/src/utils/sync-utils.ts +65 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @sylphx/flow
|
|
2
2
|
|
|
3
|
+
## 1.4.12
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- d88d280: Show missing templates in sync preview:
|
|
8
|
+
- Added "Will install (new templates)" section
|
|
9
|
+
- Users can now see which templates will be newly installed
|
|
10
|
+
- Better visibility into what changes sync will make
|
|
11
|
+
|
|
12
|
+
## 1.4.11
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- 22ddfb9: Fix sync to dynamically scan templates instead of hardcoding (CRITICAL):
|
|
17
|
+
- Now scans assets/ directory at runtime for agents, slash commands, and rules
|
|
18
|
+
- Prevents sync from breaking when templates change
|
|
19
|
+
- Old commands (commit, context, explain, review, test) now correctly detected as unknown files
|
|
20
|
+
- New commands (cleanup, improve, polish, quality, release) properly recognized as Flow templates
|
|
21
|
+
|
|
3
22
|
## 1.4.10
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
package/package.json
CHANGED
package/src/utils/sync-utils.ts
CHANGED
|
@@ -3,20 +3,37 @@ import path from 'node:path';
|
|
|
3
3
|
import chalk from 'chalk';
|
|
4
4
|
import type { Target } from '../types.js';
|
|
5
5
|
import { MCP_SERVER_REGISTRY } from '../config/servers.js';
|
|
6
|
+
import { getAgentsDir, getSlashCommandsDir, getRulesDir } from './paths.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
|
-
*
|
|
9
|
+
* Scan directory for .md files and return basenames
|
|
9
10
|
*/
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
function scanTemplateDir(dir: string): string[] {
|
|
12
|
+
if (!fs.existsSync(dir)) return [];
|
|
13
|
+
|
|
14
|
+
try {
|
|
15
|
+
return fs.readdirSync(dir, { withFileTypes: true })
|
|
16
|
+
.filter((f) => f.isFile() && f.name.endsWith('.md'))
|
|
17
|
+
.map((f) => f.name);
|
|
18
|
+
} catch {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Flow template filenames (scanned from assets at runtime)
|
|
25
|
+
*/
|
|
26
|
+
const FLOW_AGENTS = scanTemplateDir(getAgentsDir());
|
|
27
|
+
const FLOW_SLASH_COMMANDS = scanTemplateDir(getSlashCommandsDir());
|
|
28
|
+
const FLOW_RULES = scanTemplateDir(getRulesDir());
|
|
13
29
|
|
|
14
30
|
/**
|
|
15
31
|
* Categorized files for sync
|
|
16
32
|
*/
|
|
17
33
|
interface CategorizedFiles {
|
|
18
|
-
inFlow: string[]; // Files that exist in Flow templates
|
|
34
|
+
inFlow: string[]; // Files that exist locally and in Flow templates (will reinstall)
|
|
19
35
|
unknown: string[]; // Files not in Flow templates (custom or removed)
|
|
36
|
+
missing: string[]; // Flow templates that don't exist locally (will install)
|
|
20
37
|
}
|
|
21
38
|
|
|
22
39
|
/**
|
|
@@ -34,11 +51,15 @@ interface SyncManifest {
|
|
|
34
51
|
}
|
|
35
52
|
|
|
36
53
|
/**
|
|
37
|
-
* Categorize files into Flow templates vs unknown
|
|
54
|
+
* Categorize files into Flow templates vs unknown, and detect missing templates
|
|
38
55
|
*/
|
|
39
56
|
function categorizeFiles(files: string[], flowTemplates: string[]): CategorizedFiles {
|
|
40
57
|
const inFlow: string[] = [];
|
|
41
58
|
const unknown: string[] = [];
|
|
59
|
+
const existingBasenames = files.map((f) => path.basename(f));
|
|
60
|
+
|
|
61
|
+
// Find missing Flow templates (in flowTemplates but not in files)
|
|
62
|
+
const missing = flowTemplates.filter((template) => !existingBasenames.includes(template));
|
|
42
63
|
|
|
43
64
|
for (const file of files) {
|
|
44
65
|
const basename = path.basename(file);
|
|
@@ -49,7 +70,7 @@ function categorizeFiles(files: string[], flowTemplates: string[]): CategorizedF
|
|
|
49
70
|
}
|
|
50
71
|
}
|
|
51
72
|
|
|
52
|
-
return { inFlow, unknown };
|
|
73
|
+
return { inFlow, unknown, missing };
|
|
53
74
|
}
|
|
54
75
|
|
|
55
76
|
/**
|
|
@@ -57,9 +78,9 @@ function categorizeFiles(files: string[], flowTemplates: string[]): CategorizedF
|
|
|
57
78
|
*/
|
|
58
79
|
export async function buildSyncManifest(cwd: string, target: Target): Promise<SyncManifest> {
|
|
59
80
|
const manifest: SyncManifest = {
|
|
60
|
-
agents: { inFlow: [], unknown: [] },
|
|
61
|
-
slashCommands: { inFlow: [], unknown: [] },
|
|
62
|
-
rules: { inFlow: [], unknown: [] },
|
|
81
|
+
agents: { inFlow: [], unknown: [], missing: [] },
|
|
82
|
+
slashCommands: { inFlow: [], unknown: [], missing: [] },
|
|
83
|
+
rules: { inFlow: [], unknown: [], missing: [] },
|
|
63
84
|
mcpServers: { inRegistry: [], notInRegistry: [] },
|
|
64
85
|
preserve: [],
|
|
65
86
|
};
|
|
@@ -198,6 +219,40 @@ export function showSyncPreview(manifest: SyncManifest, cwd: string): void {
|
|
|
198
219
|
}
|
|
199
220
|
}
|
|
200
221
|
|
|
222
|
+
// Missing templates section (will be installed)
|
|
223
|
+
const hasMissingFiles =
|
|
224
|
+
manifest.agents.missing.length > 0 ||
|
|
225
|
+
manifest.slashCommands.missing.length > 0 ||
|
|
226
|
+
manifest.rules.missing.length > 0;
|
|
227
|
+
|
|
228
|
+
if (hasMissingFiles) {
|
|
229
|
+
console.log(chalk.green('Will install (new templates):\n'));
|
|
230
|
+
|
|
231
|
+
if (manifest.agents.missing.length > 0) {
|
|
232
|
+
console.log(chalk.dim(' Agents:'));
|
|
233
|
+
manifest.agents.missing.forEach((file) => {
|
|
234
|
+
console.log(chalk.dim(` + ${file}`));
|
|
235
|
+
});
|
|
236
|
+
console.log('');
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (manifest.slashCommands.missing.length > 0) {
|
|
240
|
+
console.log(chalk.dim(' Commands:'));
|
|
241
|
+
manifest.slashCommands.missing.forEach((file) => {
|
|
242
|
+
console.log(chalk.dim(` + ${file}`));
|
|
243
|
+
});
|
|
244
|
+
console.log('');
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (manifest.rules.missing.length > 0) {
|
|
248
|
+
console.log(chalk.dim(' Rules:'));
|
|
249
|
+
manifest.rules.missing.forEach((file) => {
|
|
250
|
+
console.log(chalk.dim(` + ${file}`));
|
|
251
|
+
});
|
|
252
|
+
console.log('');
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
201
256
|
// Unknown files section
|
|
202
257
|
const hasUnknownFiles =
|
|
203
258
|
manifest.agents.unknown.length > 0 ||
|