@sylphx/flow 3.13.2 → 3.14.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 +27 -0
- package/assets/agents/builder.md +9 -1
- package/package.json +1 -1
- package/src/core/template-loader.ts +9 -3
- package/src/index.ts +2 -2
- package/src/services/auto-upgrade.ts +15 -5
- package/src/utils/config/target-utils.ts +12 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# @sylphx/flow
|
|
2
2
|
|
|
3
|
+
## 3.14.0 (2026-02-04)
|
|
4
|
+
|
|
5
|
+
### ✨ Features
|
|
6
|
+
|
|
7
|
+
- **builder:** expand tech stack with modern React libraries ([af758b0](https://github.com/SylphxAI/flow/commit/af758b0847f450349a192385ccc2d466e0ce1a7f))
|
|
8
|
+
|
|
9
|
+
### 🐛 Bug Fixes
|
|
10
|
+
|
|
11
|
+
- **builder:** use Pragmatic Drag and Drop over dnd-kit ([75db518](https://github.com/SylphxAI/flow/commit/75db518f392ebebce65fa59739be03a983a0ed95))
|
|
12
|
+
|
|
13
|
+
### ♻️ Refactoring
|
|
14
|
+
|
|
15
|
+
- **builder:** consolidate tech stack to single best choice per category ([b149175](https://github.com/SylphxAI/flow/commit/b149175889c7838bf8f0a56459c0bd9ca811d01f))
|
|
16
|
+
- **builder:** replace Radix UI with Base UI in tech stack ([a4e81df](https://github.com/SylphxAI/flow/commit/a4e81dfcd382030e99c49fe60082aafe033e3981))
|
|
17
|
+
|
|
18
|
+
## 3.13.4 (2026-02-04)
|
|
19
|
+
|
|
20
|
+
### ♻️ Refactoring
|
|
21
|
+
|
|
22
|
+
- **builder:** replace Radix UI with Base UI in tech stack ([a4e81df](https://github.com/SylphxAI/flow/commit/a4e81dfcd382030e99c49fe60082aafe033e3981))
|
|
23
|
+
|
|
24
|
+
## 3.13.3 (2026-02-04)
|
|
25
|
+
|
|
26
|
+
### ♻️ Refactoring
|
|
27
|
+
|
|
28
|
+
- **builder:** replace Radix UI with Base UI in tech stack ([a4e81df](https://github.com/SylphxAI/flow/commit/a4e81dfcd382030e99c49fe60082aafe033e3981))
|
|
29
|
+
|
|
3
30
|
## 3.13.2 (2026-02-04)
|
|
4
31
|
|
|
5
32
|
### ♻️ Refactoring
|
package/assets/agents/builder.md
CHANGED
|
@@ -50,7 +50,15 @@ State-of-the-art industrial standard. Every time. Would you stake your reputatio
|
|
|
50
50
|
|
|
51
51
|
**Database & Infrastructure:** Neon PostgreSQL, Upstash Workflow, Vercel, Vercel Blob, Modal (serverless long-running)
|
|
52
52
|
|
|
53
|
-
**UI & Styling:**
|
|
53
|
+
**UI & Styling:** Base UI, Tailwind CSS v4 (CSS-first), Motion v12 (animation)
|
|
54
|
+
|
|
55
|
+
**Forms:** React Hook Form + Zod
|
|
56
|
+
|
|
57
|
+
**Tables & Lists:** TanStack Table, TanStack Virtual
|
|
58
|
+
|
|
59
|
+
**Interactions:** Pragmatic Drag and Drop, Tiptap (rich text), react-day-picker (date), Sonner (toast)
|
|
60
|
+
|
|
61
|
+
**File Upload:** Uppy
|
|
54
62
|
|
|
55
63
|
**AI:** AI SDK v6+
|
|
56
64
|
|
package/package.json
CHANGED
|
@@ -114,10 +114,14 @@ export class TemplateLoader {
|
|
|
114
114
|
const domainPath = path.join(skillsDir, domain);
|
|
115
115
|
const stat = await fs.stat(domainPath);
|
|
116
116
|
|
|
117
|
-
if (!stat.isDirectory())
|
|
117
|
+
if (!stat.isDirectory()) {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
118
120
|
|
|
119
121
|
const skillFile = path.join(domainPath, 'SKILL.md');
|
|
120
|
-
if (!existsSync(skillFile))
|
|
122
|
+
if (!existsSync(skillFile)) {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
121
125
|
|
|
122
126
|
const content = await fs.readFile(skillFile, 'utf-8');
|
|
123
127
|
return { name: `${domain}/SKILL.md`, content };
|
|
@@ -155,7 +159,9 @@ export class TemplateLoader {
|
|
|
155
159
|
const filePath = path.join(singleFilesDir, entry);
|
|
156
160
|
const stat = await fs.stat(filePath);
|
|
157
161
|
|
|
158
|
-
if (!stat.isFile())
|
|
162
|
+
if (!stat.isFile()) {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
159
165
|
|
|
160
166
|
const content = await fs.readFile(filePath, 'utf-8');
|
|
161
167
|
return { path: entry, content };
|
package/src/index.ts
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { Command } from 'commander';
|
|
8
|
+
// @ts-expect-error - Bun resolves JSON imports
|
|
9
|
+
import pkg from '../package.json';
|
|
8
10
|
import { executeFlow } from './commands/flow/execute-v2.js';
|
|
9
11
|
import {
|
|
10
12
|
doctorCommand,
|
|
@@ -17,8 +19,6 @@ import {
|
|
|
17
19
|
import { hookCommand } from './commands/hook-command.js';
|
|
18
20
|
import { settingsCommand } from './commands/settings-command.js';
|
|
19
21
|
import { UserCancelledError } from './utils/errors.js';
|
|
20
|
-
// @ts-expect-error - Bun resolves JSON imports
|
|
21
|
-
import pkg from '../package.json';
|
|
22
22
|
|
|
23
23
|
const VERSION = pkg.version;
|
|
24
24
|
|
|
@@ -79,7 +79,9 @@ export class AutoUpgrade {
|
|
|
79
79
|
private async shouldCheck(intervalMs: number): Promise<boolean> {
|
|
80
80
|
try {
|
|
81
81
|
const info = await this.readVersionInfo();
|
|
82
|
-
if (!info?.lastCheckTime)
|
|
82
|
+
if (!info?.lastCheckTime) {
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
83
85
|
return Date.now() - info.lastCheckTime >= intervalMs;
|
|
84
86
|
} catch {
|
|
85
87
|
return true;
|
|
@@ -111,7 +113,9 @@ export class AutoUpgrade {
|
|
|
111
113
|
lastCheckTime: Date.now(),
|
|
112
114
|
});
|
|
113
115
|
|
|
114
|
-
if (!latestVersion)
|
|
116
|
+
if (!latestVersion) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
115
119
|
|
|
116
120
|
// Upgrade if newer version available
|
|
117
121
|
if (latestVersion !== currentVersion) {
|
|
@@ -152,9 +156,15 @@ export class AutoUpgrade {
|
|
|
152
156
|
const { stdout } = await execAsync('which flow || where flow');
|
|
153
157
|
const flowPath = stdout.trim().toLowerCase();
|
|
154
158
|
|
|
155
|
-
if (flowPath.includes('bun'))
|
|
156
|
-
|
|
157
|
-
|
|
159
|
+
if (flowPath.includes('bun')) {
|
|
160
|
+
return 'bun';
|
|
161
|
+
}
|
|
162
|
+
if (flowPath.includes('pnpm')) {
|
|
163
|
+
return 'pnpm';
|
|
164
|
+
}
|
|
165
|
+
if (flowPath.includes('yarn')) {
|
|
166
|
+
return 'yarn';
|
|
167
|
+
}
|
|
158
168
|
} catch {
|
|
159
169
|
// Fall through
|
|
160
170
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { parse as parseYaml, stringify as stringifyYaml } from 'yaml';
|
|
4
|
-
import type { MCPServerConfigUnion, TargetConfig } from '../../types.js';
|
|
5
4
|
import type { FrontMatterMetadata } from '../../types/target-config.types.js';
|
|
5
|
+
import type { MCPServerConfigUnion, TargetConfig } from '../../types.js';
|
|
6
6
|
import { readJSONCFile, writeJSONCFile } from '../files/jsonc.js';
|
|
7
7
|
import { pathSecurity, sanitize } from '../security/security.js';
|
|
8
8
|
|
|
@@ -95,7 +95,9 @@ export const fileUtils = {
|
|
|
95
95
|
* YAML utilities for targets
|
|
96
96
|
*/
|
|
97
97
|
export const yamlUtils = {
|
|
98
|
-
async extractFrontMatter(
|
|
98
|
+
async extractFrontMatter(
|
|
99
|
+
content: string
|
|
100
|
+
): Promise<{ metadata: FrontMatterMetadata; content: string }> {
|
|
99
101
|
const yamlRegex = /^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/;
|
|
100
102
|
const match = content.match(yamlRegex);
|
|
101
103
|
|
|
@@ -140,7 +142,10 @@ export const yamlUtils = {
|
|
|
140
142
|
return yamlRegex.test(content);
|
|
141
143
|
},
|
|
142
144
|
|
|
143
|
-
async ensureFrontMatter(
|
|
145
|
+
async ensureFrontMatter(
|
|
146
|
+
content: string,
|
|
147
|
+
defaultMetadata: FrontMatterMetadata = {}
|
|
148
|
+
): Promise<string> {
|
|
144
149
|
if (yamlUtils.hasValidFrontMatter(content)) {
|
|
145
150
|
return content;
|
|
146
151
|
}
|
|
@@ -161,7 +166,10 @@ export const yamlUtils = {
|
|
|
161
166
|
return metadata || {};
|
|
162
167
|
},
|
|
163
168
|
|
|
164
|
-
async updateAgentMetadata(
|
|
169
|
+
async updateAgentMetadata(
|
|
170
|
+
content: string,
|
|
171
|
+
updates: Partial<FrontMatterMetadata>
|
|
172
|
+
): Promise<string> {
|
|
165
173
|
const { metadata: existingMetadata, content: baseContent } =
|
|
166
174
|
await yamlUtils.extractFrontMatter(content);
|
|
167
175
|
const updatedMetadata = { ...existingMetadata, ...updates };
|