flowmind 1.5.0 → 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 +19 -0
- package/core/sdd-agent-sync.js +109 -9
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,12 +2,30 @@
|
|
|
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
|
+
|
|
14
|
+
## [1.5.1] - 2026-07-01
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
- Clarified that FlowMind can keep normal MCP and learned-binding usage working even when no AI model is configured, as long as local knowledge has been accumulated
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
- Release notes now highlight the AI-less MCP usage path more explicitly for npm readers
|
|
21
|
+
|
|
5
22
|
## [1.5.0] - 2026-07-01
|
|
6
23
|
|
|
7
24
|
### Added
|
|
8
25
|
- `resource --sync-sdd-agent` now imports local `sdd-agent` bindings, scenes, and component state into FlowMind without touching remote services
|
|
9
26
|
- Passive learning can now auto-promote repeated resource-binding choices into reusable skill preferences after enough successful local runs
|
|
10
27
|
- Passive scene learning can now turn repeated successful scene executions into reusable default scene preferences
|
|
28
|
+
- Accumulated local knowledge can now drive repeated MCP workflows even without configuring an AI model, so learned bindings and scene preferences still keep the tool useful in MCP-only setups
|
|
11
29
|
- `resource-bind` can now save business-specific MCP, address, token, namespace, and project bindings into local learning files
|
|
12
30
|
- Runtime context now injects matched learned bindings so follow-up skills can reuse the saved business connection automatically
|
|
13
31
|
|
|
@@ -20,6 +38,7 @@
|
|
|
20
38
|
- Binding-style requests such as `绑定发布平台 mcp=friday-auto-flow token=xxx env=uat` now route through `resource-bind` reliably instead of being swallowed by execution skills
|
|
21
39
|
- Startup now avoids a false `Missing required field: version` warning when local config files do not exist yet
|
|
22
40
|
- `flowmind tui` and `flowmind dashboard` now refuse to start inside managed Codex/Claude-style CLI hosts where nested fullscreen input can terminate the outer session
|
|
41
|
+
- CLI and TUI entrypoints now fail more predictably in managed terminal hosts instead of letting nested fullscreen behavior break the outer session
|
|
23
42
|
|
|
24
43
|
## [1.4.8] - 2026-06-30
|
|
25
44
|
|
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