@synergenius/flow-weaver 0.17.0 → 0.17.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/dist/api/index.d.ts +4 -1
- package/dist/api/index.js +4 -1
- package/dist/api/templates.js +2 -2
- package/dist/api/validate.d.ts +2 -2
- package/dist/api/validate.js +6 -6
- package/dist/api/validation-registry.d.ts +10 -0
- package/dist/api/validation-registry.js +10 -0
- package/dist/ast/types.d.ts +91 -4
- package/dist/built-in-nodes/invoke-workflow.d.ts +1 -1
- package/dist/built-in-nodes/invoke-workflow.js +1 -1
- package/dist/chevrotain-parser/connect-parser.js +25 -7
- package/dist/cli/commands/compile.d.ts +5 -9
- package/dist/cli/commands/compile.js +21 -14
- package/dist/cli/commands/dev.d.ts +2 -13
- package/dist/cli/commands/dev.js +10 -204
- package/dist/cli/commands/doctor.js +6 -3
- package/dist/cli/commands/export.d.ts +8 -17
- package/dist/cli/commands/export.js +8 -17
- package/dist/cli/commands/init-personas.d.ts +17 -6
- package/dist/cli/commands/init-personas.js +73 -24
- package/dist/cli/commands/init.d.ts +5 -2
- package/dist/cli/commands/init.js +73 -42
- package/dist/cli/commands/mcp-setup.d.ts +7 -0
- package/dist/cli/commands/mcp-setup.js +16 -1
- package/dist/cli/flow-weaver.mjs +71002 -70385
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +9 -7
- package/dist/cli/templates/index.d.ts +20 -1
- package/dist/cli/templates/index.js +66 -15
- package/dist/cli/templates/nodes/human-approval.js +2 -3
- package/dist/cli/templates/nodes/rag-retriever.js +1 -1
- package/dist/constants.d.ts +7 -0
- package/dist/constants.js +13 -3
- package/dist/context/index.js +13 -3
- package/dist/deployment/config/loader.js +2 -1
- package/dist/deployment/core/adapters.d.ts +1 -25
- package/dist/deployment/core/adapters.js +0 -95
- package/dist/deployment/core/formatters.d.ts +0 -15
- package/dist/deployment/core/formatters.js +0 -24
- package/dist/deployment/index.d.ts +7 -5
- package/dist/deployment/index.js +8 -5
- package/dist/deployment/types.d.ts +2 -45
- package/dist/diagram/html-viewer.js +65 -32
- package/dist/diagram/renderer.js +9 -6
- package/dist/diagram/theme.js +4 -0
- package/dist/diagram/types.d.ts +2 -0
- package/dist/doc-metadata/extractors/annotations.js +5 -5
- package/dist/doc-metadata/extractors/cli-commands.js +1 -1
- package/dist/doc-metadata/extractors/mcp-tools.js +1 -2
- package/dist/docs/index.d.ts +28 -1
- package/dist/docs/index.js +95 -28
- package/dist/export/index.d.ts +2 -3
- package/dist/{deployment/targets/cicd-base.d.ts → extensions/cicd/base-target.d.ts} +35 -36
- package/dist/{deployment/targets/cicd-base.js → extensions/cicd/base-target.js} +97 -57
- package/dist/{validation/cicd-detection.d.ts → extensions/cicd/detection.d.ts} +2 -2
- package/dist/{validation/cicd-detection.js → extensions/cicd/detection.js} +13 -1
- package/dist/extensions/cicd/docs/cicd.md +395 -0
- package/dist/extensions/cicd/index.d.ts +10 -0
- package/dist/extensions/cicd/index.js +10 -0
- package/dist/extensions/cicd/register.d.ts +11 -0
- package/dist/extensions/cicd/register.js +62 -0
- package/dist/extensions/cicd/rules.d.ts +30 -0
- package/dist/{validation/cicd-rules.js → extensions/cicd/rules.js} +60 -56
- package/dist/extensions/cicd/tag-handler.d.ts +14 -0
- package/dist/extensions/cicd/tag-handler.js +488 -0
- package/dist/{cli/templates/workflows → extensions/cicd/templates}/cicd-docker.d.ts +1 -1
- package/dist/{cli/templates/workflows → extensions/cicd/templates}/cicd-matrix.d.ts +1 -1
- package/dist/{cli/templates/workflows → extensions/cicd/templates}/cicd-multi-env.d.ts +1 -1
- package/dist/{cli/templates/workflows → extensions/cicd/templates}/cicd-test-deploy.d.ts +1 -1
- package/dist/extensions/index.d.ts +12 -0
- package/dist/extensions/index.js +12 -0
- package/dist/extensions/inngest/dev-mode.d.ts +9 -0
- package/dist/extensions/inngest/dev-mode.js +213 -0
- package/dist/{generator/inngest.d.ts → extensions/inngest/generator.d.ts} +2 -2
- package/dist/{generator/inngest.js → extensions/inngest/generator.js} +4 -4
- package/dist/extensions/inngest/index.d.ts +2 -0
- package/dist/extensions/inngest/index.js +2 -0
- package/dist/extensions/inngest/register.d.ts +6 -0
- package/dist/extensions/inngest/register.js +23 -0
- package/dist/extensions/inngest/templates/ai-agent-durable.d.ts +8 -0
- package/dist/{cli/templates/workflows → extensions/inngest/templates}/ai-agent-durable.js +8 -8
- package/dist/{cli/templates/workflows → extensions/inngest/templates}/ai-pipeline-durable.d.ts +2 -2
- package/dist/{cli/templates/workflows → extensions/inngest/templates}/ai-pipeline-durable.js +7 -7
- package/dist/generated-version.d.ts +1 -1
- package/dist/generated-version.js +1 -1
- package/dist/generator/compile-target-registry.d.ts +20 -0
- package/dist/generator/compile-target-registry.js +20 -0
- package/dist/generator/dev-mode-registry.d.ts +27 -0
- package/dist/generator/dev-mode-registry.js +20 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3 -0
- package/dist/jsdoc-parser.d.ts +12 -114
- package/dist/jsdoc-parser.js +57 -362
- package/dist/marketplace/index.d.ts +2 -2
- package/dist/marketplace/index.js +1 -1
- package/dist/marketplace/registry.d.ts +39 -1
- package/dist/marketplace/registry.js +77 -0
- package/dist/marketplace/types.d.ts +76 -3
- package/dist/mcp/server.d.ts +1 -0
- package/dist/mcp/server.js +2 -0
- package/dist/mcp/tools-export.js +3 -3
- package/dist/mcp/tools-query.js +17 -11
- package/dist/mcp/tools-template.js +1 -1
- package/dist/parser/tag-registry.d.ts +47 -0
- package/dist/parser/tag-registry.js +57 -0
- package/dist/parser.d.ts +3 -0
- package/dist/parser.js +10 -23
- package/dist/validation/rule-registry.d.ts +36 -0
- package/dist/validation/rule-registry.js +37 -0
- package/dist/validator.js +3 -3
- package/docs/reference/concepts.md +2 -1
- package/docs/reference/deployment.md +21 -0
- package/docs/reference/jsdoc-grammar.md +242 -1
- package/docs/reference/scaffold.md +0 -6
- package/package.json +9 -1
- package/dist/cli/templates/workflows/ai-agent-durable.d.ts +0 -8
- package/dist/export/templates.d.ts +0 -24
- package/dist/export/templates.js +0 -186
- package/dist/validation/cicd-rules.d.ts +0 -62
- /package/dist/{cli/templates/workflows → extensions/cicd/templates}/cicd-docker.js +0 -0
- /package/dist/{cli/templates/workflows → extensions/cicd/templates}/cicd-matrix.js +0 -0
- /package/dist/{cli/templates/workflows → extensions/cicd/templates}/cicd-multi-env.js +0 -0
- /package/dist/{cli/templates/workflows → extensions/cicd/templates}/cicd-test-deploy.js +0 -0
package/dist/jsdoc-parser.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Parses @flowWeaver annotations from JSDoc comments.
|
|
5
5
|
*/
|
|
6
|
-
import { isExecutePort, isSuccessPort, isFailurePort, isScopedMandatoryPort, KNOWN_NODETYPE_TAGS,
|
|
6
|
+
import { isExecutePort, isSuccessPort, isFailurePort, isScopedMandatoryPort, KNOWN_NODETYPE_TAGS, KNOWN_PATTERN_TAGS, STANDARD_JSDOC_TAGS, getKnownWorkflowTags, } from './constants.js';
|
|
7
7
|
import { inferDataTypeFromTS } from './type-mappings.js';
|
|
8
8
|
import { findClosestMatches } from './utils/string-distance.js';
|
|
9
9
|
import { parsePortLine, parseNodeLine, parseConnectLine, parsePositionLine, parseScopeLine, parseMapLine, parsePathLine, parseFanOutLine, parseFanInLine, parseCoerceLine, parseTriggerLine, parseCancelOnLine, parseThrottleLine, } from './chevrotain-parser/index.js';
|
|
@@ -99,9 +99,11 @@ function extractCallbackParamType(callbackType, paramName) {
|
|
|
99
99
|
}
|
|
100
100
|
export class JSDocParser {
|
|
101
101
|
/**
|
|
102
|
-
* Parse @flowWeaver nodeType from JSDoc comments
|
|
102
|
+
* Parse @flowWeaver nodeType from JSDoc comments.
|
|
103
|
+
* When a TagHandlerRegistry is provided, unknown tags are checked against it
|
|
104
|
+
* before being reported as warnings.
|
|
103
105
|
*/
|
|
104
|
-
parseNodeType(func, warnings) {
|
|
106
|
+
parseNodeType(func, warnings, tagRegistry) {
|
|
105
107
|
const jsdocs = func.getJsDocs();
|
|
106
108
|
if (jsdocs.length === 0)
|
|
107
109
|
return null;
|
|
@@ -199,11 +201,17 @@ export class JSDocParser {
|
|
|
199
201
|
config.deploy = config.deploy || {};
|
|
200
202
|
this.parseDeployTag(tag, config.deploy);
|
|
201
203
|
break;
|
|
202
|
-
default:
|
|
204
|
+
default: {
|
|
203
205
|
// D: Context validation - tags that belong to other block types
|
|
204
206
|
if (tagName === 'param' || tagName === 'returns' || tagName === 'return') {
|
|
205
207
|
warnings.push(`@${tagName} is for workflows, not node types. Use @input/@output instead.`);
|
|
206
208
|
}
|
|
209
|
+
else if (tagRegistry && tagRegistry.has(tagName)) {
|
|
210
|
+
// Delegate to pack-contributed tag handler
|
|
211
|
+
if (!config.deploy)
|
|
212
|
+
config.deploy = {};
|
|
213
|
+
tagRegistry.handle(tagName, comment, 'nodeType', config.deploy, warnings);
|
|
214
|
+
}
|
|
207
215
|
else if (!KNOWN_NODETYPE_TAGS.has(tagName) && !STANDARD_JSDOC_TAGS.has(tagName)) {
|
|
208
216
|
// C: Unknown tag detection with suggestions
|
|
209
217
|
const suggestions = findClosestMatches(tagName, [...KNOWN_NODETYPE_TAGS]);
|
|
@@ -211,14 +219,17 @@ export class JSDocParser {
|
|
|
211
219
|
warnings.push(`Unknown annotation @${tagName} in nodeType block.${hint}`);
|
|
212
220
|
}
|
|
213
221
|
break;
|
|
222
|
+
}
|
|
214
223
|
}
|
|
215
224
|
});
|
|
216
225
|
return config;
|
|
217
226
|
}
|
|
218
227
|
/**
|
|
219
|
-
* Parse @flowWeaver workflow from JSDoc comments
|
|
228
|
+
* Parse @flowWeaver workflow from JSDoc comments.
|
|
229
|
+
* When a TagHandlerRegistry is provided, unknown tags are checked against it
|
|
230
|
+
* before being reported as warnings.
|
|
220
231
|
*/
|
|
221
|
-
parseWorkflow(func, warnings) {
|
|
232
|
+
parseWorkflow(func, warnings, tagRegistry) {
|
|
222
233
|
const jsdocs = func.getJsDocs();
|
|
223
234
|
if (jsdocs.length === 0)
|
|
224
235
|
return null;
|
|
@@ -298,7 +309,7 @@ export class JSDocParser {
|
|
|
298
309
|
this.parseCoerceTag(tag, config, warnings);
|
|
299
310
|
break;
|
|
300
311
|
case 'trigger':
|
|
301
|
-
this.parseTriggerTag(tag, config, warnings);
|
|
312
|
+
this.parseTriggerTag(tag, config, warnings, tagRegistry);
|
|
302
313
|
break;
|
|
303
314
|
case 'cancelOn':
|
|
304
315
|
this.parseCancelOnTag(tag, config, warnings);
|
|
@@ -320,17 +331,9 @@ export class JSDocParser {
|
|
|
320
331
|
case 'throttle':
|
|
321
332
|
this.parseThrottleTag(tag, config, warnings);
|
|
322
333
|
break;
|
|
323
|
-
// ── CI/CD + deployment annotations (delegated to helper) ──
|
|
324
334
|
case 'deploy':
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
case 'cache':
|
|
328
|
-
case 'artifact':
|
|
329
|
-
case 'environment':
|
|
330
|
-
case 'matrix':
|
|
331
|
-
case 'service':
|
|
332
|
-
case 'concurrency':
|
|
333
|
-
this.handleDeploymentTag(tagName, tag, config, warnings);
|
|
335
|
+
config.deploy = config.deploy || {};
|
|
336
|
+
this.parseDeployTag(tag, config.deploy);
|
|
334
337
|
break;
|
|
335
338
|
case 'param':
|
|
336
339
|
this.parseParamTag(tag, config, func, warnings);
|
|
@@ -339,7 +342,7 @@ export class JSDocParser {
|
|
|
339
342
|
case 'returns':
|
|
340
343
|
this.parseReturnTag(tag, config, func, warnings);
|
|
341
344
|
break;
|
|
342
|
-
default:
|
|
345
|
+
default: {
|
|
343
346
|
// D: Context validation - tags that belong to other block types
|
|
344
347
|
if (tagName === 'color' || tagName === 'icon' || tagName === 'tag') {
|
|
345
348
|
warnings.push(`@${tagName} is for node types, not workflows. Use it on @flowWeaver nodeType instead.`);
|
|
@@ -347,13 +350,23 @@ export class JSDocParser {
|
|
|
347
350
|
else if (tagName === 'input' || tagName === 'output' || tagName === 'step') {
|
|
348
351
|
warnings.push(`@${tagName} is for node types, not workflows. Use @param/@returns for workflows.`);
|
|
349
352
|
}
|
|
350
|
-
else if (
|
|
351
|
-
//
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
353
|
+
else if (tagRegistry && tagRegistry.has(tagName)) {
|
|
354
|
+
// Delegate to pack-contributed tag handler
|
|
355
|
+
if (!config.deploy)
|
|
356
|
+
config.deploy = {};
|
|
357
|
+
tagRegistry.handle(tagName, comment, 'workflow', config.deploy, warnings);
|
|
358
|
+
}
|
|
359
|
+
else {
|
|
360
|
+
const knownTags = getKnownWorkflowTags(tagRegistry?.getRegisteredTags());
|
|
361
|
+
if (!knownTags.has(tagName) && !STANDARD_JSDOC_TAGS.has(tagName)) {
|
|
362
|
+
// C: Unknown tag detection with suggestions
|
|
363
|
+
const suggestions = findClosestMatches(tagName, [...knownTags]);
|
|
364
|
+
const hint = suggestions.length > 0 ? ` Did you mean @${suggestions[0]}?` : '';
|
|
365
|
+
warnings.push(`Unknown annotation @${tagName} in workflow block.${hint}`);
|
|
366
|
+
}
|
|
355
367
|
}
|
|
356
368
|
break;
|
|
369
|
+
}
|
|
357
370
|
}
|
|
358
371
|
});
|
|
359
372
|
return config;
|
|
@@ -1035,74 +1048,29 @@ export class JSDocParser {
|
|
|
1035
1048
|
}
|
|
1036
1049
|
/**
|
|
1037
1050
|
* Parse @trigger tag using Chevrotain parser.
|
|
1051
|
+
* Delegates unrecognized trigger formats to the tag registry (e.g. CI/CD triggers).
|
|
1038
1052
|
*/
|
|
1039
|
-
parseTriggerTag(tag, config, warnings) {
|
|
1053
|
+
parseTriggerTag(tag, config, warnings, tagRegistry) {
|
|
1040
1054
|
const comment = (tag.getCommentText() || '').trim();
|
|
1041
|
-
//
|
|
1042
|
-
const cicdTriggerMatch = comment.match(/^(push|pull_request|dispatch|tag|schedule)\b(.*)?$/);
|
|
1043
|
-
if (cicdTriggerMatch) {
|
|
1044
|
-
this.parseCICDTrigger(cicdTriggerMatch[1], cicdTriggerMatch[2]?.trim() || '', config, warnings);
|
|
1045
|
-
return;
|
|
1046
|
-
}
|
|
1047
|
-
// Also detect cron="..." as a schedule trigger for CI/CD
|
|
1048
|
-
const cronOnlyMatch = comment.match(/^cron\s*=\s*"([^"]+)"/);
|
|
1049
|
-
if (cronOnlyMatch && !comment.includes('event=')) {
|
|
1050
|
-
// Could be CI/CD schedule or existing FW cron — store both
|
|
1051
|
-
config.cicdTriggers = config.cicdTriggers || [];
|
|
1052
|
-
config.cicdTriggers.push({ type: 'schedule', cron: cronOnlyMatch[1] });
|
|
1053
|
-
}
|
|
1054
|
-
// Existing FW trigger parsing (event= and/or cron=)
|
|
1055
|
+
// Try core FW trigger parsing first (event= and/or cron=)
|
|
1055
1056
|
const result = parseTriggerLine(`@trigger ${comment}`, warnings);
|
|
1056
|
-
if (
|
|
1057
|
-
//
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1057
|
+
if (result) {
|
|
1058
|
+
// Merge: multiple @trigger tags accumulate (event + cron can be separate tags)
|
|
1059
|
+
config.trigger = config.trigger || {};
|
|
1060
|
+
if (result.event)
|
|
1061
|
+
config.trigger.event = result.event;
|
|
1062
|
+
if (result.cron)
|
|
1063
|
+
config.trigger.cron = result.cron;
|
|
1061
1064
|
return;
|
|
1062
1065
|
}
|
|
1063
|
-
//
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
}
|
|
1070
|
-
/**
|
|
1071
|
-
* Parse a CI/CD-specific trigger type (push, pull_request, dispatch, tag, schedule).
|
|
1072
|
-
*/
|
|
1073
|
-
parseCICDTrigger(type, rest, config, _warnings) {
|
|
1074
|
-
config.cicdTriggers = config.cicdTriggers || [];
|
|
1075
|
-
const triggerType = type;
|
|
1076
|
-
const trigger = { type: triggerType };
|
|
1077
|
-
// Parse key="value" pairs from rest
|
|
1078
|
-
const branchesMatch = rest.match(/branches\s*=\s*"([^"]+)"/);
|
|
1079
|
-
if (branchesMatch)
|
|
1080
|
-
trigger.branches = branchesMatch[1].split(',').map(b => b.trim());
|
|
1081
|
-
const pathsMatch = rest.match(/(?<![a-z])paths\s*=\s*"([^"]+)"/);
|
|
1082
|
-
if (pathsMatch)
|
|
1083
|
-
trigger.paths = pathsMatch[1].split(',').map(p => p.trim());
|
|
1084
|
-
const pathsIgnoreMatch = rest.match(/paths-ignore\s*=\s*"([^"]+)"/);
|
|
1085
|
-
if (pathsIgnoreMatch)
|
|
1086
|
-
trigger.pathsIgnore = pathsIgnoreMatch[1].split(',').map(p => p.trim());
|
|
1087
|
-
const typesMatch = rest.match(/types\s*=\s*"([^"]+)"/);
|
|
1088
|
-
if (typesMatch)
|
|
1089
|
-
trigger.types = typesMatch[1].split(',').map(t => t.trim());
|
|
1090
|
-
const patternMatch = rest.match(/pattern\s*=\s*"([^"]+)"/);
|
|
1091
|
-
if (patternMatch)
|
|
1092
|
-
trigger.pattern = patternMatch[1];
|
|
1093
|
-
const cronMatch = rest.match(/cron\s*=\s*"([^"]+)"/);
|
|
1094
|
-
if (cronMatch)
|
|
1095
|
-
trigger.cron = cronMatch[1];
|
|
1096
|
-
const inputsMatch = rest.match(/inputs\s*=\s*"([^"]+)"/);
|
|
1097
|
-
if (inputsMatch) {
|
|
1098
|
-
trigger.inputs = {};
|
|
1099
|
-
for (const input of inputsMatch[1].split(',')) {
|
|
1100
|
-
const name = input.trim();
|
|
1101
|
-
if (name)
|
|
1102
|
-
trigger.inputs[name] = {};
|
|
1103
|
-
}
|
|
1066
|
+
// Not a core trigger. Delegate to domain-specific handlers (e.g. CI/CD).
|
|
1067
|
+
if (tagRegistry && tagRegistry.has('_cicdTrigger')) {
|
|
1068
|
+
if (!config.deploy)
|
|
1069
|
+
config.deploy = {};
|
|
1070
|
+
tagRegistry.handle('_cicdTrigger', comment, 'workflow', config.deploy, warnings);
|
|
1071
|
+
return;
|
|
1104
1072
|
}
|
|
1105
|
-
|
|
1073
|
+
warnings.push(`Invalid @trigger format: @trigger ${comment}`);
|
|
1106
1074
|
}
|
|
1107
1075
|
/**
|
|
1108
1076
|
* Parse @cancelOn tag using Chevrotain parser.
|
|
@@ -1128,54 +1096,14 @@ export class JSDocParser {
|
|
|
1128
1096
|
}
|
|
1129
1097
|
config.throttle = result;
|
|
1130
1098
|
}
|
|
1131
|
-
// ── Deployment dispatch + @deploy parser ───────────────────────────
|
|
1132
|
-
/**
|
|
1133
|
-
* Dispatch a CI/CD or @deploy tag to the appropriate parser.
|
|
1134
|
-
* Consolidates all deployment-related cases from the main switch.
|
|
1135
|
-
*/
|
|
1136
|
-
handleDeploymentTag(tagName, tag, config, warnings) {
|
|
1137
|
-
switch (tagName) {
|
|
1138
|
-
case 'deploy':
|
|
1139
|
-
config.deploy = config.deploy || {};
|
|
1140
|
-
this.parseDeployTag(tag, config.deploy);
|
|
1141
|
-
break;
|
|
1142
|
-
case 'secret':
|
|
1143
|
-
this.parseSecretTag(tag, config, warnings);
|
|
1144
|
-
break;
|
|
1145
|
-
case 'runner': {
|
|
1146
|
-
const comment = (tag.getCommentText() || '').trim().replace(/^["']|["']$/g, '');
|
|
1147
|
-
if (comment)
|
|
1148
|
-
config.runner = comment;
|
|
1149
|
-
break;
|
|
1150
|
-
}
|
|
1151
|
-
case 'cache':
|
|
1152
|
-
this.parseCacheTag(tag, config, warnings);
|
|
1153
|
-
break;
|
|
1154
|
-
case 'artifact':
|
|
1155
|
-
this.parseArtifactTag(tag, config, warnings);
|
|
1156
|
-
break;
|
|
1157
|
-
case 'environment':
|
|
1158
|
-
this.parseEnvironmentTag(tag, config, warnings);
|
|
1159
|
-
break;
|
|
1160
|
-
case 'matrix':
|
|
1161
|
-
this.parseMatrixTag(tag, config, warnings);
|
|
1162
|
-
break;
|
|
1163
|
-
case 'service':
|
|
1164
|
-
this.parseServiceTag(tag, config, warnings);
|
|
1165
|
-
break;
|
|
1166
|
-
case 'concurrency':
|
|
1167
|
-
this.parseConcurrencyTag(tag, config, warnings);
|
|
1168
|
-
break;
|
|
1169
|
-
}
|
|
1170
|
-
}
|
|
1171
1099
|
/**
|
|
1172
1100
|
* Parse @deploy tag.
|
|
1173
1101
|
* Format: @deploy <target> key=value key2="value with spaces" key3=123 key4=true
|
|
1174
1102
|
*
|
|
1175
1103
|
* Examples:
|
|
1176
1104
|
* @deploy github-actions action="actions/checkout@v4"
|
|
1177
|
-
* @deploy
|
|
1178
|
-
* @deploy
|
|
1105
|
+
* @deploy my-target durableSteps=true framework="next" retries=3
|
|
1106
|
+
* @deploy another-target memory=256 timeout=30
|
|
1179
1107
|
*
|
|
1180
1108
|
* Values are auto-coerced: "true"/"false" → boolean, numeric strings → number.
|
|
1181
1109
|
*/
|
|
@@ -1194,7 +1122,8 @@ export class JSDocParser {
|
|
|
1194
1122
|
if (!rest)
|
|
1195
1123
|
return;
|
|
1196
1124
|
// Parse key=value and key="value with spaces" pairs
|
|
1197
|
-
|
|
1125
|
+
// The quoted value pattern handles escaped quotes: "echo \"hello\""
|
|
1126
|
+
const kvRegex = /(\w[\w-]*)\s*=\s*(?:"((?:[^"\\]|\\.)*)"|([\S]+))/g;
|
|
1198
1127
|
let match;
|
|
1199
1128
|
while ((match = kvRegex.exec(rest)) !== null) {
|
|
1200
1129
|
const key = match[1];
|
|
@@ -1224,240 +1153,6 @@ export class JSDocParser {
|
|
|
1224
1153
|
}
|
|
1225
1154
|
}
|
|
1226
1155
|
}
|
|
1227
|
-
// ── CI/CD annotation parsers ───────────────────────────────────────
|
|
1228
|
-
/**
|
|
1229
|
-
* Parse @secret tag.
|
|
1230
|
-
* Format: @secret NAME - description
|
|
1231
|
-
* Optional: @secret NAME scope="deploy" platform="github" - description
|
|
1232
|
-
*/
|
|
1233
|
-
parseSecretTag(_tag, config, warnings) {
|
|
1234
|
-
const comment = (_tag.getCommentText() || '').trim();
|
|
1235
|
-
if (!comment) {
|
|
1236
|
-
warnings.push('Empty @secret tag. Expected: @secret SECRET_NAME - description');
|
|
1237
|
-
return;
|
|
1238
|
-
}
|
|
1239
|
-
// Parse: NAME [key=value ...] [- description]
|
|
1240
|
-
const match = comment.match(/^(\S+)(.*?)(?:\s+-\s+(.*))?$/);
|
|
1241
|
-
if (!match) {
|
|
1242
|
-
warnings.push(`Invalid @secret format: @secret ${comment}`);
|
|
1243
|
-
return;
|
|
1244
|
-
}
|
|
1245
|
-
const name = match[1];
|
|
1246
|
-
const attrs = match[2] || '';
|
|
1247
|
-
const description = match[3]?.trim();
|
|
1248
|
-
const secret = { name };
|
|
1249
|
-
if (description)
|
|
1250
|
-
secret.description = description;
|
|
1251
|
-
// Parse optional key=value attributes
|
|
1252
|
-
const scopeMatch = attrs.match(/scope\s*=\s*"([^"]+)"/);
|
|
1253
|
-
if (scopeMatch)
|
|
1254
|
-
secret.scope = scopeMatch[1];
|
|
1255
|
-
const platformMatch = attrs.match(/platform\s*=\s*"([^"]+)"/);
|
|
1256
|
-
if (platformMatch) {
|
|
1257
|
-
const validPlatforms = ['github', 'gitlab', 'all'];
|
|
1258
|
-
const p = platformMatch[1];
|
|
1259
|
-
if (validPlatforms.includes(p)) {
|
|
1260
|
-
secret.platform = p;
|
|
1261
|
-
}
|
|
1262
|
-
else {
|
|
1263
|
-
warnings.push(`Invalid @secret platform "${platformMatch[1]}". Must be: github, gitlab, or all`);
|
|
1264
|
-
}
|
|
1265
|
-
}
|
|
1266
|
-
config.secrets = config.secrets || [];
|
|
1267
|
-
config.secrets.push(secret);
|
|
1268
|
-
}
|
|
1269
|
-
/**
|
|
1270
|
-
* Parse @cache tag.
|
|
1271
|
-
* Format: @cache strategy [key="file"] [path="dir"]
|
|
1272
|
-
*/
|
|
1273
|
-
parseCacheTag(_tag, config, warnings) {
|
|
1274
|
-
const comment = (_tag.getCommentText() || '').trim();
|
|
1275
|
-
if (!comment) {
|
|
1276
|
-
warnings.push('Empty @cache tag. Expected: @cache npm key="package-lock.json"');
|
|
1277
|
-
return;
|
|
1278
|
-
}
|
|
1279
|
-
const parts = comment.match(/^(\S+)(.*)?$/);
|
|
1280
|
-
if (!parts) {
|
|
1281
|
-
warnings.push(`Invalid @cache format: @cache ${comment}`);
|
|
1282
|
-
return;
|
|
1283
|
-
}
|
|
1284
|
-
const cache = { strategy: parts[1] };
|
|
1285
|
-
const rest = parts[2] || '';
|
|
1286
|
-
const keyMatch = rest.match(/key\s*=\s*"([^"]+)"/);
|
|
1287
|
-
if (keyMatch)
|
|
1288
|
-
cache.key = keyMatch[1];
|
|
1289
|
-
const pathMatch = rest.match(/path\s*=\s*"([^"]+)"/);
|
|
1290
|
-
if (pathMatch)
|
|
1291
|
-
cache.path = pathMatch[1];
|
|
1292
|
-
config.caches = config.caches || [];
|
|
1293
|
-
config.caches.push(cache);
|
|
1294
|
-
}
|
|
1295
|
-
/**
|
|
1296
|
-
* Parse @artifact tag.
|
|
1297
|
-
* Format: @artifact name path="dist/" [retention=5]
|
|
1298
|
-
*/
|
|
1299
|
-
parseArtifactTag(_tag, config, warnings) {
|
|
1300
|
-
const comment = (_tag.getCommentText() || '').trim();
|
|
1301
|
-
if (!comment) {
|
|
1302
|
-
warnings.push('Empty @artifact tag. Expected: @artifact name path="dist/"');
|
|
1303
|
-
return;
|
|
1304
|
-
}
|
|
1305
|
-
const nameMatch = comment.match(/^(\S+)/);
|
|
1306
|
-
if (!nameMatch) {
|
|
1307
|
-
warnings.push(`Invalid @artifact format: @artifact ${comment}`);
|
|
1308
|
-
return;
|
|
1309
|
-
}
|
|
1310
|
-
const pathMatch = comment.match(/path\s*=\s*"([^"]+)"/);
|
|
1311
|
-
if (!pathMatch) {
|
|
1312
|
-
warnings.push(`@artifact requires path="...": @artifact ${comment}`);
|
|
1313
|
-
return;
|
|
1314
|
-
}
|
|
1315
|
-
const artifact = {
|
|
1316
|
-
name: nameMatch[1],
|
|
1317
|
-
path: pathMatch[1],
|
|
1318
|
-
};
|
|
1319
|
-
const retentionMatch = comment.match(/retention\s*=\s*(\d+)/);
|
|
1320
|
-
if (retentionMatch)
|
|
1321
|
-
artifact.retention = parseInt(retentionMatch[1], 10);
|
|
1322
|
-
config.artifacts = config.artifacts || [];
|
|
1323
|
-
config.artifacts.push(artifact);
|
|
1324
|
-
}
|
|
1325
|
-
/**
|
|
1326
|
-
* Parse @environment tag.
|
|
1327
|
-
* Format: @environment name [url="..."] [reviewers=N]
|
|
1328
|
-
*/
|
|
1329
|
-
parseEnvironmentTag(_tag, config, warnings) {
|
|
1330
|
-
const comment = (_tag.getCommentText() || '').trim();
|
|
1331
|
-
if (!comment) {
|
|
1332
|
-
warnings.push('Empty @environment tag. Expected: @environment production url="https://app.com"');
|
|
1333
|
-
return;
|
|
1334
|
-
}
|
|
1335
|
-
const nameMatch = comment.match(/^(\S+)/);
|
|
1336
|
-
if (!nameMatch) {
|
|
1337
|
-
warnings.push(`Invalid @environment format: @environment ${comment}`);
|
|
1338
|
-
return;
|
|
1339
|
-
}
|
|
1340
|
-
const env = { name: nameMatch[1] };
|
|
1341
|
-
const urlMatch = comment.match(/url\s*=\s*"([^"]+)"/);
|
|
1342
|
-
if (urlMatch)
|
|
1343
|
-
env.url = urlMatch[1];
|
|
1344
|
-
const reviewersMatch = comment.match(/reviewers\s*=\s*(\d+)/);
|
|
1345
|
-
if (reviewersMatch)
|
|
1346
|
-
env.reviewers = parseInt(reviewersMatch[1], 10);
|
|
1347
|
-
config.environments = config.environments || [];
|
|
1348
|
-
config.environments.push(env);
|
|
1349
|
-
}
|
|
1350
|
-
/**
|
|
1351
|
-
* Parse @matrix tag.
|
|
1352
|
-
* Format: @matrix dim1="val1,val2" dim2="val3,val4"
|
|
1353
|
-
* Or: @matrix include dim1="val1" dim2="val2"
|
|
1354
|
-
* Or: @matrix exclude dim1="val1" dim2="val2"
|
|
1355
|
-
*/
|
|
1356
|
-
parseMatrixTag(_tag, config, warnings) {
|
|
1357
|
-
const comment = (_tag.getCommentText() || '').trim();
|
|
1358
|
-
if (!comment) {
|
|
1359
|
-
warnings.push('Empty @matrix tag. Expected: @matrix node="18,20,22" os="ubuntu-latest"');
|
|
1360
|
-
return;
|
|
1361
|
-
}
|
|
1362
|
-
config.matrix = config.matrix || { dimensions: {} };
|
|
1363
|
-
// Check for include/exclude prefix
|
|
1364
|
-
const isInclude = comment.startsWith('include ');
|
|
1365
|
-
const isExclude = comment.startsWith('exclude ');
|
|
1366
|
-
if (isInclude || isExclude) {
|
|
1367
|
-
const rest = comment.slice(isInclude ? 8 : 8);
|
|
1368
|
-
const entry = {};
|
|
1369
|
-
const kvRegex = /(\w[\w-]*)\s*=\s*"([^"]+)"/g;
|
|
1370
|
-
let m;
|
|
1371
|
-
while ((m = kvRegex.exec(rest)) !== null) {
|
|
1372
|
-
entry[m[1]] = m[2];
|
|
1373
|
-
}
|
|
1374
|
-
if (Object.keys(entry).length > 0) {
|
|
1375
|
-
if (isInclude) {
|
|
1376
|
-
config.matrix.include = config.matrix.include || [];
|
|
1377
|
-
config.matrix.include.push(entry);
|
|
1378
|
-
}
|
|
1379
|
-
else {
|
|
1380
|
-
config.matrix.exclude = config.matrix.exclude || [];
|
|
1381
|
-
config.matrix.exclude.push(entry);
|
|
1382
|
-
}
|
|
1383
|
-
}
|
|
1384
|
-
return;
|
|
1385
|
-
}
|
|
1386
|
-
// Regular dimensions: key="val1,val2"
|
|
1387
|
-
const kvRegex = /(\w[\w-]*)\s*=\s*"([^"]+)"/g;
|
|
1388
|
-
let m;
|
|
1389
|
-
while ((m = kvRegex.exec(comment)) !== null) {
|
|
1390
|
-
config.matrix.dimensions[m[1]] = m[2].split(',').map(v => v.trim());
|
|
1391
|
-
}
|
|
1392
|
-
}
|
|
1393
|
-
/**
|
|
1394
|
-
* Parse @service tag.
|
|
1395
|
-
* Format: @service name image="..." [env="K=V,K2=V2"] [ports="5432:5432"]
|
|
1396
|
-
*/
|
|
1397
|
-
parseServiceTag(_tag, config, warnings) {
|
|
1398
|
-
const comment = (_tag.getCommentText() || '').trim();
|
|
1399
|
-
if (!comment) {
|
|
1400
|
-
warnings.push('Empty @service tag. Expected: @service postgres image="postgres:16"');
|
|
1401
|
-
return;
|
|
1402
|
-
}
|
|
1403
|
-
const nameMatch = comment.match(/^(\S+)/);
|
|
1404
|
-
if (!nameMatch) {
|
|
1405
|
-
warnings.push(`Invalid @service format: @service ${comment}`);
|
|
1406
|
-
return;
|
|
1407
|
-
}
|
|
1408
|
-
const imageMatch = comment.match(/image\s*=\s*"([^"]+)"/);
|
|
1409
|
-
if (!imageMatch) {
|
|
1410
|
-
warnings.push(`@service requires image="...": @service ${comment}`);
|
|
1411
|
-
return;
|
|
1412
|
-
}
|
|
1413
|
-
const svc = {
|
|
1414
|
-
name: nameMatch[1],
|
|
1415
|
-
image: imageMatch[1],
|
|
1416
|
-
};
|
|
1417
|
-
const envMatch = comment.match(/env\s*=\s*"([^"]+)"/);
|
|
1418
|
-
if (envMatch) {
|
|
1419
|
-
svc.env = {};
|
|
1420
|
-
for (const pair of envMatch[1].split(',')) {
|
|
1421
|
-
const [k, ...vParts] = pair.split('=');
|
|
1422
|
-
if (k && vParts.length > 0)
|
|
1423
|
-
svc.env[k.trim()] = vParts.join('=').trim();
|
|
1424
|
-
}
|
|
1425
|
-
}
|
|
1426
|
-
const portsMatch = comment.match(/ports\s*=\s*"([^"]+)"/);
|
|
1427
|
-
if (portsMatch) {
|
|
1428
|
-
svc.ports = portsMatch[1].split(',').map(p => p.trim());
|
|
1429
|
-
}
|
|
1430
|
-
config.services = config.services || [];
|
|
1431
|
-
config.services.push(svc);
|
|
1432
|
-
}
|
|
1433
|
-
/**
|
|
1434
|
-
* Parse @concurrency tag.
|
|
1435
|
-
* Format: @concurrency group="name" [cancel-in-progress=true]
|
|
1436
|
-
*/
|
|
1437
|
-
parseConcurrencyTag(_tag, config, warnings) {
|
|
1438
|
-
const comment = (_tag.getCommentText() || '').trim();
|
|
1439
|
-
if (!comment) {
|
|
1440
|
-
warnings.push('Empty @concurrency tag. Expected: @concurrency group="deploy"');
|
|
1441
|
-
return;
|
|
1442
|
-
}
|
|
1443
|
-
const groupMatch = comment.match(/group\s*=\s*"([^"]+)"/);
|
|
1444
|
-
if (!groupMatch) {
|
|
1445
|
-
// Try bare word: @concurrency deploy
|
|
1446
|
-
const bareMatch = comment.match(/^(\S+)/);
|
|
1447
|
-
if (bareMatch) {
|
|
1448
|
-
config.concurrency = { group: bareMatch[1], cancelInProgress: false };
|
|
1449
|
-
}
|
|
1450
|
-
else {
|
|
1451
|
-
warnings.push(`Invalid @concurrency format: @concurrency ${comment}`);
|
|
1452
|
-
}
|
|
1453
|
-
return;
|
|
1454
|
-
}
|
|
1455
|
-
const cancelMatch = comment.match(/cancel-in-progress\s*=\s*(true|false)/);
|
|
1456
|
-
config.concurrency = {
|
|
1457
|
-
group: groupMatch[1],
|
|
1458
|
-
cancelInProgress: cancelMatch ? cancelMatch[1] === 'true' : false,
|
|
1459
|
-
};
|
|
1460
|
-
}
|
|
1461
1156
|
/**
|
|
1462
1157
|
* Parse default value from string
|
|
1463
1158
|
*/
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* Flow Weaver Marketplace — discover, install, and publish reusable
|
|
5
5
|
* node types, workflows, and patterns via npm.
|
|
6
6
|
*/
|
|
7
|
-
export type { TMarketplaceManifest, TManifestNodeType, TManifestWorkflow, TManifestPattern, TManifestExportTarget, TManifestPort, TValidationIssue, TValidationSeverity, TPackageValidationResult, TMarketplacePackageInfo, TInstalledPackage, TMarketInitConfig, } from './types.js';
|
|
7
|
+
export type { TMarketplaceManifest, TManifestNodeType, TManifestWorkflow, TManifestPattern, TManifestExportTarget, TManifestPort, TValidationIssue, TValidationSeverity, TPackageValidationResult, TMarketplacePackageInfo, TInstalledPackage, TMarketInitConfig, TManifestTagHandler, TManifestValidationRuleSet, TManifestDocTopic, TManifestInitContribution, } from './types.js';
|
|
8
8
|
export { generateManifest, writeManifest, readManifest, type GenerateManifestOptions, type GenerateManifestResult, } from './manifest.js';
|
|
9
9
|
export { validatePackage } from './validator.js';
|
|
10
|
-
export { searchPackages, listInstalledPackages, getInstalledPackageManifest, type SearchOptions, } from './registry.js';
|
|
10
|
+
export { searchPackages, listInstalledPackages, getInstalledPackageManifest, discoverTagHandlers, discoverValidationRuleSets, discoverDocTopics, discoverInitContributions, type SearchOptions, type TDiscoveredTagHandler, type TDiscoveredValidationRuleSet, type TDiscoveredDocTopic, type TDiscoveredInitContribution, } from './registry.js';
|
|
11
11
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -6,5 +6,5 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export { generateManifest, writeManifest, readManifest, } from './manifest.js';
|
|
8
8
|
export { validatePackage } from './validator.js';
|
|
9
|
-
export { searchPackages, listInstalledPackages, getInstalledPackageManifest, } from './registry.js';
|
|
9
|
+
export { searchPackages, listInstalledPackages, getInstalledPackageManifest, discoverTagHandlers, discoverValidationRuleSets, discoverDocTopics, discoverInitContributions, } from './registry.js';
|
|
10
10
|
//# sourceMappingURL=index.js.map
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* `flowweaver-marketplace-pack` keyword for discovery, and scans
|
|
6
6
|
* `node_modules/` for locally installed packages.
|
|
7
7
|
*/
|
|
8
|
-
import type { TMarketplaceManifest, TMarketplacePackageInfo, TInstalledPackage } from './types.js';
|
|
8
|
+
import type { TMarketplaceManifest, TMarketplacePackageInfo, TInstalledPackage, TManifestTagHandler, TManifestValidationRuleSet, TManifestDocTopic, TManifestInitContribution } from './types.js';
|
|
9
9
|
export interface SearchOptions {
|
|
10
10
|
/** Search query text */
|
|
11
11
|
query?: string;
|
|
@@ -27,4 +27,42 @@ export declare function listInstalledPackages(projectDir: string): Promise<TInst
|
|
|
27
27
|
* Read the manifest for a specific installed package.
|
|
28
28
|
*/
|
|
29
29
|
export declare function getInstalledPackageManifest(projectDir: string, packageName: string): TMarketplaceManifest | null;
|
|
30
|
+
export type TDiscoveredTagHandler = TManifestTagHandler & {
|
|
31
|
+
/** Absolute path to the handler module */
|
|
32
|
+
absoluteFile: string;
|
|
33
|
+
/** Package name this handler belongs to */
|
|
34
|
+
packageName: string;
|
|
35
|
+
};
|
|
36
|
+
export type TDiscoveredValidationRuleSet = TManifestValidationRuleSet & {
|
|
37
|
+
/** Absolute path to the rule set module */
|
|
38
|
+
absoluteFile: string;
|
|
39
|
+
/** Package name this rule set belongs to */
|
|
40
|
+
packageName: string;
|
|
41
|
+
};
|
|
42
|
+
export type TDiscoveredDocTopic = TManifestDocTopic & {
|
|
43
|
+
/** Absolute path to the markdown file */
|
|
44
|
+
absoluteFile: string;
|
|
45
|
+
/** Package name this doc belongs to */
|
|
46
|
+
packageName: string;
|
|
47
|
+
};
|
|
48
|
+
export type TDiscoveredInitContribution = TManifestInitContribution & {
|
|
49
|
+
/** Package name this contribution belongs to */
|
|
50
|
+
packageName: string;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Discover all tag handlers from installed pack manifests.
|
|
54
|
+
*/
|
|
55
|
+
export declare function discoverTagHandlers(projectDir: string): Promise<TDiscoveredTagHandler[]>;
|
|
56
|
+
/**
|
|
57
|
+
* Discover all validation rule sets from installed pack manifests.
|
|
58
|
+
*/
|
|
59
|
+
export declare function discoverValidationRuleSets(projectDir: string): Promise<TDiscoveredValidationRuleSet[]>;
|
|
60
|
+
/**
|
|
61
|
+
* Discover all doc topics from installed pack manifests.
|
|
62
|
+
*/
|
|
63
|
+
export declare function discoverDocTopics(projectDir: string): Promise<TDiscoveredDocTopic[]>;
|
|
64
|
+
/**
|
|
65
|
+
* Discover all init contributions from installed pack manifests.
|
|
66
|
+
*/
|
|
67
|
+
export declare function discoverInitContributions(projectDir: string): Promise<TDiscoveredInitContribution[]>;
|
|
30
68
|
//# sourceMappingURL=registry.d.ts.map
|