flowmind 1.5.1 → 1.5.2
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 +9 -0
- package/core/sdd-agent-sync.js +109 -9
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [1.5.2] - 2026-07-01
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- `sdd-agent-sync` now imports workflow resources from local `auto-flow` learning data into FlowMind
|
|
9
|
+
- Workflow sync now writes a local `workflow` resource, a `workflow` component config, and a reusable `workflow` binding for `friday-auto-flow`
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
- `flowmind resource --sync-sdd-agent` can now seed the workflow MCP path automatically, so `auto-flow` no longer depends on a manual local binding
|
|
13
|
+
|
|
5
14
|
## [1.5.1] - 2026-07-01
|
|
6
15
|
|
|
7
16
|
### Added
|
package/core/sdd-agent-sync.js
CHANGED
|
@@ -46,11 +46,19 @@ function isObject(value) {
|
|
|
46
46
|
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
function sanitizeResourceConfig(sddConfig) {
|
|
49
|
+
function sanitizeResourceConfig(sddConfig, skillBindingData = {}) {
|
|
50
|
+
const resources = { ...(sddConfig.resources || {}) };
|
|
51
|
+
if (!resources.workflow) {
|
|
52
|
+
const workflowResource = buildWorkflowResource(skillBindingData);
|
|
53
|
+
if (workflowResource) {
|
|
54
|
+
resources.workflow = workflowResource;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
50
58
|
return {
|
|
51
59
|
version: sddConfig.version || '1.0',
|
|
52
60
|
lastUpdated: new Date().toISOString(),
|
|
53
|
-
resources
|
|
61
|
+
resources,
|
|
54
62
|
mcpServers: sddConfig.mcpServers || {},
|
|
55
63
|
aliases: sddConfig.aliases || {},
|
|
56
64
|
metadata: {
|
|
@@ -171,7 +179,91 @@ function buildLogBindings(resourceConfig = {}) {
|
|
|
171
179
|
}));
|
|
172
180
|
}
|
|
173
181
|
|
|
174
|
-
function
|
|
182
|
+
function buildWorkflowResource(skillBindingData = {}) {
|
|
183
|
+
const workflowBinding = skillBindingData.bindings?.['auto-flow'];
|
|
184
|
+
if (!workflowBinding) return null;
|
|
185
|
+
|
|
186
|
+
const learningCount = workflowBinding.learningCount || (workflowBinding.records || []).length || (workflowBinding.rules || []).length;
|
|
187
|
+
|
|
188
|
+
return {
|
|
189
|
+
enabled: true,
|
|
190
|
+
mcpServer: 'friday-auto-flow',
|
|
191
|
+
bindings: {
|
|
192
|
+
'auto-flow': {
|
|
193
|
+
name: '自动部署',
|
|
194
|
+
skill: 'auto-flow',
|
|
195
|
+
provider: 'friday-flow',
|
|
196
|
+
mcpServer: 'friday-auto-flow',
|
|
197
|
+
learningCount,
|
|
198
|
+
lastLearning: workflowBinding.lastLearning || null,
|
|
199
|
+
records: workflowBinding.records || [],
|
|
200
|
+
rules: workflowBinding.rules || []
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
defaultBinding: 'auto-flow'
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function buildWorkflowBindings(skillBindingData = {}) {
|
|
208
|
+
const workflowBinding = skillBindingData.bindings?.['auto-flow'];
|
|
209
|
+
if (!workflowBinding) return [];
|
|
210
|
+
|
|
211
|
+
const ruleSummaries = (workflowBinding.records || []).map((record) => record.summary).filter(Boolean);
|
|
212
|
+
const ruleActions = (workflowBinding.rules || []).map((rule) => rule.action).filter(Boolean);
|
|
213
|
+
const keywords = [
|
|
214
|
+
'auto-flow',
|
|
215
|
+
'workflow',
|
|
216
|
+
'pipeline',
|
|
217
|
+
'deploy',
|
|
218
|
+
'deployment',
|
|
219
|
+
'部署',
|
|
220
|
+
'发布',
|
|
221
|
+
'上线',
|
|
222
|
+
'流水线',
|
|
223
|
+
...ruleSummaries,
|
|
224
|
+
...ruleActions
|
|
225
|
+
];
|
|
226
|
+
|
|
227
|
+
return [{
|
|
228
|
+
id: 'sdd-workflow-auto-flow',
|
|
229
|
+
timestamp: new Date().toISOString(),
|
|
230
|
+
business: '自动部署',
|
|
231
|
+
aliases: [
|
|
232
|
+
'auto-flow',
|
|
233
|
+
'workflow',
|
|
234
|
+
'pipeline',
|
|
235
|
+
'飞流',
|
|
236
|
+
'飞流部署',
|
|
237
|
+
'部署',
|
|
238
|
+
'发布',
|
|
239
|
+
'上线',
|
|
240
|
+
'流水线'
|
|
241
|
+
],
|
|
242
|
+
componentType: 'workflow',
|
|
243
|
+
provider: 'friday-flow',
|
|
244
|
+
mcpServer: 'friday-auto-flow',
|
|
245
|
+
source: 'sdd-agent-sync',
|
|
246
|
+
keywords: [...new Set(keywords.filter(Boolean))],
|
|
247
|
+
connection: {
|
|
248
|
+
skill: 'auto-flow',
|
|
249
|
+
learningCount: workflowBinding.learningCount || 0,
|
|
250
|
+
lastLearning: workflowBinding.lastLearning || null,
|
|
251
|
+
records: workflowBinding.records || [],
|
|
252
|
+
rules: workflowBinding.rules || []
|
|
253
|
+
},
|
|
254
|
+
metadata: {
|
|
255
|
+
source: 'sdd-agent',
|
|
256
|
+
resourceType: 'workflow',
|
|
257
|
+
bindingKey: 'auto-flow'
|
|
258
|
+
},
|
|
259
|
+
stats: {
|
|
260
|
+
useCount: 0,
|
|
261
|
+
lastUsed: null
|
|
262
|
+
}
|
|
263
|
+
}];
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
function convertResourceBindings(sddConfig, skillBindingData = {}) {
|
|
175
267
|
const resources = sddConfig.resources || {};
|
|
176
268
|
const aliasIndex = buildAliasIndex(sddConfig.aliases);
|
|
177
269
|
const bindings = [];
|
|
@@ -189,6 +281,8 @@ function convertResourceBindings(sddConfig) {
|
|
|
189
281
|
}
|
|
190
282
|
}
|
|
191
283
|
|
|
284
|
+
bindings.push(...buildWorkflowBindings(skillBindingData));
|
|
285
|
+
|
|
192
286
|
return bindings;
|
|
193
287
|
}
|
|
194
288
|
|
|
@@ -223,8 +317,9 @@ function convertSceneMappings(sceneData = {}) {
|
|
|
223
317
|
}));
|
|
224
318
|
}
|
|
225
319
|
|
|
226
|
-
function buildComponentConfig(sddConfig) {
|
|
320
|
+
function buildComponentConfig(sddConfig, skillBindingData = {}) {
|
|
227
321
|
const resources = sddConfig.resources || {};
|
|
322
|
+
const workflowResource = resources.workflow || buildWorkflowResource(skillBindingData);
|
|
228
323
|
const components = {};
|
|
229
324
|
|
|
230
325
|
if (resources.sls?.enabled) {
|
|
@@ -297,13 +392,13 @@ function buildComponentConfig(sddConfig) {
|
|
|
297
392
|
};
|
|
298
393
|
}
|
|
299
394
|
|
|
300
|
-
if (
|
|
395
|
+
if (workflowResource?.enabled && workflowResource.mcpServer) {
|
|
301
396
|
components.workflow = {
|
|
302
397
|
default: 'friday-flow',
|
|
303
398
|
providers: {
|
|
304
399
|
'friday-flow': {
|
|
305
400
|
enabled: true,
|
|
306
|
-
mcpServer: normalizeMcpServer(
|
|
401
|
+
mcpServer: normalizeMcpServer(workflowResource.mcpServer)
|
|
307
402
|
}
|
|
308
403
|
}
|
|
309
404
|
};
|
|
@@ -393,6 +488,7 @@ async function syncSddAgentToFlowMind(options = {}) {
|
|
|
393
488
|
const targetHome = options.targetHome || getHomeDir();
|
|
394
489
|
const sourceConfigPath = path.join(sourceDir, 'resource-config.json');
|
|
395
490
|
const sourceScenesPath = path.join(sourceDir, 'learning', 'scene-mappings.json');
|
|
491
|
+
const sourceSkillBindingsPath = path.join(sourceDir, 'learning', 'skill-bindings.json');
|
|
396
492
|
const targetDir = path.join(targetHome, '.flowmind');
|
|
397
493
|
const targetLearningDir = path.join(targetDir, 'learning');
|
|
398
494
|
|
|
@@ -402,6 +498,8 @@ async function syncSddAgentToFlowMind(options = {}) {
|
|
|
402
498
|
|
|
403
499
|
const sddConfig = await fs.readJson(sourceConfigPath);
|
|
404
500
|
const sddScenes = await readJsonIfExists(sourceScenesPath, { mappings: [] });
|
|
501
|
+
const sddSkillBindings = await readJsonIfExists(sourceSkillBindingsPath, { version: '1.0', bindings: {} });
|
|
502
|
+
sddConfig.skillBindings = sddSkillBindings;
|
|
405
503
|
|
|
406
504
|
const targetResourceConfigPath = path.join(targetDir, 'resource-config.json');
|
|
407
505
|
const targetComponentConfigPath = path.join(targetDir, 'component-config.json');
|
|
@@ -413,9 +511,9 @@ async function syncSddAgentToFlowMind(options = {}) {
|
|
|
413
511
|
const existingBindings = await readJsonIfExists(targetBindingsPath, { version: '1.0', bindings: [] });
|
|
414
512
|
const existingScenes = await readJsonIfExists(targetScenesPath, { version: '1.0', mappings: [] });
|
|
415
513
|
|
|
416
|
-
const nextResourceConfig = deepMerge(existingResourceConfig, sanitizeResourceConfig(sddConfig));
|
|
417
|
-
const nextComponentConfig = deepMerge(existingComponentConfig, buildComponentConfig(sddConfig));
|
|
418
|
-
const importedBindings = convertResourceBindings(sddConfig);
|
|
514
|
+
const nextResourceConfig = deepMerge(existingResourceConfig, sanitizeResourceConfig(sddConfig, sddSkillBindings));
|
|
515
|
+
const nextComponentConfig = deepMerge(existingComponentConfig, buildComponentConfig(sddConfig, sddSkillBindings));
|
|
516
|
+
const importedBindings = convertResourceBindings(sddConfig, sddSkillBindings);
|
|
419
517
|
const nextBindings = {
|
|
420
518
|
version: existingBindings.version || '1.0',
|
|
421
519
|
lastUpdated: new Date().toISOString(),
|
|
@@ -461,6 +559,8 @@ module.exports = {
|
|
|
461
559
|
deepMerge,
|
|
462
560
|
mergeBindings,
|
|
463
561
|
mergeScenes,
|
|
562
|
+
buildWorkflowBindings,
|
|
563
|
+
buildWorkflowResource,
|
|
464
564
|
normalizeMcpServer,
|
|
465
565
|
sanitizeResourceConfig,
|
|
466
566
|
syncSddAgentToFlowMind
|
package/package.json
CHANGED