@kairos-sdk/core 0.5.1 → 0.6.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/README.md +121 -15
- package/dist/{chunk-VPPWTMRJ.js → chunk-2ZHNO37N.js} +48 -4
- package/dist/chunk-2ZHNO37N.js.map +1 -0
- package/dist/chunk-GG4B4TYG.js +153 -0
- package/dist/chunk-GG4B4TYG.js.map +1 -0
- package/dist/{chunk-MYAGTDQ2.js → chunk-PCNW5ZUD.js} +2 -2
- package/dist/chunk-SC6CLQZB.js +144 -0
- package/dist/chunk-SC6CLQZB.js.map +1 -0
- package/dist/chunk-SQS4QHDH.js +44 -0
- package/dist/chunk-SQS4QHDH.js.map +1 -0
- package/dist/{chunk-V2IZBZGB.js → chunk-STG7Z2SS.js} +2 -2
- package/dist/{chunk-GVZKMS53.js → chunk-YOQTEVDB.js} +4 -4
- package/dist/cli.cjs +647 -3
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +239 -4
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +385 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +86 -3
- package/dist/index.d.ts +86 -3
- package/dist/index.js +19 -5
- package/dist/mcp-server.cjs +47 -3
- package/dist/mcp-server.cjs.map +1 -1
- package/dist/mcp-server.js +2 -2
- package/dist/pack-builder-RTQWXGIS.js +9 -0
- package/dist/pack-builder-RTQWXGIS.js.map +1 -0
- package/dist/pack-exporter-KFNLSP5V.js +7 -0
- package/dist/pack-exporter-KFNLSP5V.js.map +1 -0
- package/dist/pack-validator-HZPB2XJ3.js +7 -0
- package/dist/pack-validator-HZPB2XJ3.js.map +1 -0
- package/dist/{reader-B5mV20H6.d.ts → reader-CfWGpL4V.d.cts} +2 -1
- package/dist/{reader-B5mV20H6.d.cts → reader-CfWGpL4V.d.ts} +2 -1
- package/dist/standalone.cjs +43 -3
- package/dist/standalone.cjs.map +1 -1
- package/dist/standalone.d.cts +1 -1
- package/dist/standalone.d.ts +1 -1
- package/dist/standalone.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-VPPWTMRJ.js.map +0 -1
- /package/dist/{chunk-MYAGTDQ2.js.map → chunk-PCNW5ZUD.js.map} +0 -0
- /package/dist/{chunk-V2IZBZGB.js.map → chunk-STG7Z2SS.js.map} +0 -0
- /package/dist/{chunk-GVZKMS53.js.map → chunk-YOQTEVDB.js.map} +0 -0
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as ClientOptions, B as BuildOptions,
|
|
2
|
-
export { A as ApiError,
|
|
1
|
+
import { C as ClientOptions, B as BuildOptions, b as BuildResult, r as N8nWorkflow, Z as WorkflowListItem, d as DeleteOptions, f as ExecutionFilter, g as ExecutionSummary, E as ExecutionDetail, T as Tag, c as CredentialRequirement } from './reader-CfWGpL4V.cjs';
|
|
2
|
+
export { A as ApiError, a as AttemptMetadata, D as DEFAULT_REGISTRY, e as DeployResult, F as FailurePattern, h as FileLibrary, G as GenerationError, i as GuardError, I as ILogger, j as IProvider, k as IWorkflowLibrary, K as KairosError, N as N8nApiClient, l as N8nConnections, m as N8nFieldStripper, n as N8nNode, o as N8nProvider, p as N8nSettings, q as N8nValidator, s as NodeRegistry, t as NullLibrary, O as OutcomeData, u as OutcomeStats, P as ProviderError, R as ResponseParseError, v as RuleFailureRate, S as ScoredEntry, w as SmokeTestResult, y as SourceKind, z as StoredWorkflow, H as SyncProgress, J as TelemetryCollector, L as TelemetryEvent, M as TelemetryReader, Q as TemplateSyncer, U as TrustLevel, V as ValidationError, W as ValidationIssue, X as ValidationResult, Y as WorkflowCluster, _ as WorkflowMatch, $ as WorkflowMetadataInput, a0 as buildSearchCorpus, a1 as clusterWorkflows, a2 as hybridScore, a3 as nullLogger, a4 as rerank, a5 as tokenize } from './reader-CfWGpL4V.cjs';
|
|
3
3
|
|
|
4
4
|
declare class Kairos {
|
|
5
5
|
private readonly provider;
|
|
@@ -34,4 +34,87 @@ declare class Kairos {
|
|
|
34
34
|
untag(workflowId: string, tagIds: string[]): Promise<void>;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
type AssumptionType = 'safe' | 'needs_confirmation' | 'blocking';
|
|
38
|
+
type PackStatus = 'draft' | 'blocked' | 'ready_for_test' | 'ready_for_activation' | 'active' | 'needs_attention';
|
|
39
|
+
interface TypedAssumption {
|
|
40
|
+
type: AssumptionType;
|
|
41
|
+
text: string;
|
|
42
|
+
}
|
|
43
|
+
interface WorkflowPlan {
|
|
44
|
+
name: string;
|
|
45
|
+
description: string;
|
|
46
|
+
purpose: string;
|
|
47
|
+
}
|
|
48
|
+
interface PackPlan {
|
|
49
|
+
businessContext: string;
|
|
50
|
+
workflows: WorkflowPlan[];
|
|
51
|
+
assumptions: TypedAssumption[];
|
|
52
|
+
sheetsColumns: Array<{
|
|
53
|
+
sheet: string;
|
|
54
|
+
columns: string[];
|
|
55
|
+
}>;
|
|
56
|
+
testChecklist: Array<{
|
|
57
|
+
workflow: string;
|
|
58
|
+
steps: string[];
|
|
59
|
+
}>;
|
|
60
|
+
}
|
|
61
|
+
interface PackWorkflowResult {
|
|
62
|
+
name: string;
|
|
63
|
+
purpose: string;
|
|
64
|
+
workflowId: string | null;
|
|
65
|
+
deployed: boolean;
|
|
66
|
+
generationAttempts: number;
|
|
67
|
+
credentialsNeeded: CredentialRequirement[];
|
|
68
|
+
error?: string;
|
|
69
|
+
}
|
|
70
|
+
interface WorkflowPackResult {
|
|
71
|
+
businessContext: string;
|
|
72
|
+
packName: string;
|
|
73
|
+
status: PackStatus;
|
|
74
|
+
workflows: PackWorkflowResult[];
|
|
75
|
+
allCredentials: Array<{
|
|
76
|
+
service: string;
|
|
77
|
+
credentialType: string;
|
|
78
|
+
}>;
|
|
79
|
+
sheetsColumns: Array<{
|
|
80
|
+
sheet: string;
|
|
81
|
+
columns: string[];
|
|
82
|
+
}>;
|
|
83
|
+
assumptions: TypedAssumption[];
|
|
84
|
+
testChecklist: Array<{
|
|
85
|
+
workflow: string;
|
|
86
|
+
steps: string[];
|
|
87
|
+
}>;
|
|
88
|
+
builtAt: string;
|
|
89
|
+
}
|
|
90
|
+
declare function derivePackStatus(pack: Pick<WorkflowPackResult, 'assumptions' | 'workflows'> & {
|
|
91
|
+
status?: PackStatus;
|
|
92
|
+
}): PackStatus;
|
|
93
|
+
declare class PackBuilder {
|
|
94
|
+
private client;
|
|
95
|
+
private kairos;
|
|
96
|
+
private model;
|
|
97
|
+
constructor(options: {
|
|
98
|
+
anthropicApiKey: string;
|
|
99
|
+
kairos: Kairos;
|
|
100
|
+
model?: string;
|
|
101
|
+
});
|
|
102
|
+
plan(businessContext: string): Promise<PackPlan>;
|
|
103
|
+
build(plan: PackPlan, options?: {
|
|
104
|
+
dryRun?: boolean;
|
|
105
|
+
activate?: boolean;
|
|
106
|
+
onProgress?: (workflow: WorkflowPlan, index: number, total: number) => void;
|
|
107
|
+
}): Promise<WorkflowPackResult>;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
declare function generateHandoff(pack: WorkflowPackResult): string;
|
|
111
|
+
|
|
112
|
+
interface PackValidationIssue {
|
|
113
|
+
type: 'duplicate_name' | 'blocking_assumption' | 'unsafe_activation' | 'schedule_conflict';
|
|
114
|
+
severity: 'error' | 'warning';
|
|
115
|
+
message: string;
|
|
116
|
+
workflows?: string[];
|
|
117
|
+
}
|
|
118
|
+
declare function validatePack(pack: WorkflowPackResult): PackValidationIssue[];
|
|
119
|
+
|
|
120
|
+
export { type AssumptionType, BuildOptions, BuildResult, ClientOptions, CredentialRequirement, DeleteOptions, ExecutionDetail, ExecutionFilter, ExecutionSummary, Kairos, N8nWorkflow, PackBuilder, type PackPlan, type PackStatus, type PackValidationIssue, type PackWorkflowResult, Tag, type TypedAssumption, WorkflowListItem, type WorkflowPackResult, type WorkflowPlan, derivePackStatus, generateHandoff, validatePack };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as ClientOptions, B as BuildOptions,
|
|
2
|
-
export { A as ApiError,
|
|
1
|
+
import { C as ClientOptions, B as BuildOptions, b as BuildResult, r as N8nWorkflow, Z as WorkflowListItem, d as DeleteOptions, f as ExecutionFilter, g as ExecutionSummary, E as ExecutionDetail, T as Tag, c as CredentialRequirement } from './reader-CfWGpL4V.js';
|
|
2
|
+
export { A as ApiError, a as AttemptMetadata, D as DEFAULT_REGISTRY, e as DeployResult, F as FailurePattern, h as FileLibrary, G as GenerationError, i as GuardError, I as ILogger, j as IProvider, k as IWorkflowLibrary, K as KairosError, N as N8nApiClient, l as N8nConnections, m as N8nFieldStripper, n as N8nNode, o as N8nProvider, p as N8nSettings, q as N8nValidator, s as NodeRegistry, t as NullLibrary, O as OutcomeData, u as OutcomeStats, P as ProviderError, R as ResponseParseError, v as RuleFailureRate, S as ScoredEntry, w as SmokeTestResult, y as SourceKind, z as StoredWorkflow, H as SyncProgress, J as TelemetryCollector, L as TelemetryEvent, M as TelemetryReader, Q as TemplateSyncer, U as TrustLevel, V as ValidationError, W as ValidationIssue, X as ValidationResult, Y as WorkflowCluster, _ as WorkflowMatch, $ as WorkflowMetadataInput, a0 as buildSearchCorpus, a1 as clusterWorkflows, a2 as hybridScore, a3 as nullLogger, a4 as rerank, a5 as tokenize } from './reader-CfWGpL4V.js';
|
|
3
3
|
|
|
4
4
|
declare class Kairos {
|
|
5
5
|
private readonly provider;
|
|
@@ -34,4 +34,87 @@ declare class Kairos {
|
|
|
34
34
|
untag(workflowId: string, tagIds: string[]): Promise<void>;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
type AssumptionType = 'safe' | 'needs_confirmation' | 'blocking';
|
|
38
|
+
type PackStatus = 'draft' | 'blocked' | 'ready_for_test' | 'ready_for_activation' | 'active' | 'needs_attention';
|
|
39
|
+
interface TypedAssumption {
|
|
40
|
+
type: AssumptionType;
|
|
41
|
+
text: string;
|
|
42
|
+
}
|
|
43
|
+
interface WorkflowPlan {
|
|
44
|
+
name: string;
|
|
45
|
+
description: string;
|
|
46
|
+
purpose: string;
|
|
47
|
+
}
|
|
48
|
+
interface PackPlan {
|
|
49
|
+
businessContext: string;
|
|
50
|
+
workflows: WorkflowPlan[];
|
|
51
|
+
assumptions: TypedAssumption[];
|
|
52
|
+
sheetsColumns: Array<{
|
|
53
|
+
sheet: string;
|
|
54
|
+
columns: string[];
|
|
55
|
+
}>;
|
|
56
|
+
testChecklist: Array<{
|
|
57
|
+
workflow: string;
|
|
58
|
+
steps: string[];
|
|
59
|
+
}>;
|
|
60
|
+
}
|
|
61
|
+
interface PackWorkflowResult {
|
|
62
|
+
name: string;
|
|
63
|
+
purpose: string;
|
|
64
|
+
workflowId: string | null;
|
|
65
|
+
deployed: boolean;
|
|
66
|
+
generationAttempts: number;
|
|
67
|
+
credentialsNeeded: CredentialRequirement[];
|
|
68
|
+
error?: string;
|
|
69
|
+
}
|
|
70
|
+
interface WorkflowPackResult {
|
|
71
|
+
businessContext: string;
|
|
72
|
+
packName: string;
|
|
73
|
+
status: PackStatus;
|
|
74
|
+
workflows: PackWorkflowResult[];
|
|
75
|
+
allCredentials: Array<{
|
|
76
|
+
service: string;
|
|
77
|
+
credentialType: string;
|
|
78
|
+
}>;
|
|
79
|
+
sheetsColumns: Array<{
|
|
80
|
+
sheet: string;
|
|
81
|
+
columns: string[];
|
|
82
|
+
}>;
|
|
83
|
+
assumptions: TypedAssumption[];
|
|
84
|
+
testChecklist: Array<{
|
|
85
|
+
workflow: string;
|
|
86
|
+
steps: string[];
|
|
87
|
+
}>;
|
|
88
|
+
builtAt: string;
|
|
89
|
+
}
|
|
90
|
+
declare function derivePackStatus(pack: Pick<WorkflowPackResult, 'assumptions' | 'workflows'> & {
|
|
91
|
+
status?: PackStatus;
|
|
92
|
+
}): PackStatus;
|
|
93
|
+
declare class PackBuilder {
|
|
94
|
+
private client;
|
|
95
|
+
private kairos;
|
|
96
|
+
private model;
|
|
97
|
+
constructor(options: {
|
|
98
|
+
anthropicApiKey: string;
|
|
99
|
+
kairos: Kairos;
|
|
100
|
+
model?: string;
|
|
101
|
+
});
|
|
102
|
+
plan(businessContext: string): Promise<PackPlan>;
|
|
103
|
+
build(plan: PackPlan, options?: {
|
|
104
|
+
dryRun?: boolean;
|
|
105
|
+
activate?: boolean;
|
|
106
|
+
onProgress?: (workflow: WorkflowPlan, index: number, total: number) => void;
|
|
107
|
+
}): Promise<WorkflowPackResult>;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
declare function generateHandoff(pack: WorkflowPackResult): string;
|
|
111
|
+
|
|
112
|
+
interface PackValidationIssue {
|
|
113
|
+
type: 'duplicate_name' | 'blocking_assumption' | 'unsafe_activation' | 'schedule_conflict';
|
|
114
|
+
severity: 'error' | 'warning';
|
|
115
|
+
message: string;
|
|
116
|
+
workflows?: string[];
|
|
117
|
+
}
|
|
118
|
+
declare function validatePack(pack: WorkflowPackResult): PackValidationIssue[];
|
|
119
|
+
|
|
120
|
+
export { type AssumptionType, BuildOptions, BuildResult, ClientOptions, CredentialRequirement, DeleteOptions, ExecutionDetail, ExecutionFilter, ExecutionSummary, Kairos, N8nWorkflow, PackBuilder, type PackPlan, type PackStatus, type PackValidationIssue, type PackWorkflowResult, Tag, type TypedAssumption, WorkflowListItem, type WorkflowPackResult, type WorkflowPlan, derivePackStatus, generateHandoff, validatePack };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Kairos
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-YOQTEVDB.js";
|
|
4
|
+
import "./chunk-STG7Z2SS.js";
|
|
5
5
|
import "./chunk-6FOFWVMG.js";
|
|
6
6
|
import {
|
|
7
7
|
GenerationError,
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
ResponseParseError,
|
|
11
11
|
TemplateSyncer,
|
|
12
12
|
ValidationError
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-PCNW5ZUD.js";
|
|
14
14
|
import {
|
|
15
15
|
ApiError,
|
|
16
16
|
DEFAULT_REGISTRY,
|
|
@@ -30,7 +30,17 @@ import {
|
|
|
30
30
|
nullLogger,
|
|
31
31
|
rerank,
|
|
32
32
|
tokenize
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-2ZHNO37N.js";
|
|
34
|
+
import {
|
|
35
|
+
PackBuilder,
|
|
36
|
+
derivePackStatus
|
|
37
|
+
} from "./chunk-GG4B4TYG.js";
|
|
38
|
+
import {
|
|
39
|
+
generateHandoff
|
|
40
|
+
} from "./chunk-SC6CLQZB.js";
|
|
41
|
+
import {
|
|
42
|
+
validatePack
|
|
43
|
+
} from "./chunk-SQS4QHDH.js";
|
|
34
44
|
export {
|
|
35
45
|
ApiError,
|
|
36
46
|
DEFAULT_REGISTRY,
|
|
@@ -45,6 +55,7 @@ export {
|
|
|
45
55
|
N8nValidator,
|
|
46
56
|
NodeRegistry,
|
|
47
57
|
NullLibrary,
|
|
58
|
+
PackBuilder,
|
|
48
59
|
ProviderError,
|
|
49
60
|
ResponseParseError,
|
|
50
61
|
TelemetryCollector,
|
|
@@ -53,9 +64,12 @@ export {
|
|
|
53
64
|
ValidationError,
|
|
54
65
|
buildSearchCorpus,
|
|
55
66
|
clusterWorkflows,
|
|
67
|
+
derivePackStatus,
|
|
68
|
+
generateHandoff,
|
|
56
69
|
hybridScore,
|
|
57
70
|
nullLogger,
|
|
58
71
|
rerank,
|
|
59
|
-
tokenize
|
|
72
|
+
tokenize,
|
|
73
|
+
validatePack
|
|
60
74
|
};
|
|
61
75
|
//# sourceMappingURL=index.js.map
|
package/dist/mcp-server.cjs
CHANGED
|
@@ -901,6 +901,7 @@ var N8nValidator = class {
|
|
|
901
901
|
this.checkRule32(workflow, issues);
|
|
902
902
|
this.checkRule33(workflow, issues);
|
|
903
903
|
this.checkRule34(workflow, issues);
|
|
904
|
+
this.checkRule35(workflow, issues);
|
|
904
905
|
if (Array.isArray(workflow.nodes)) {
|
|
905
906
|
const nodeById = new Map(workflow.nodes.map((n) => [n.id, n.type]));
|
|
906
907
|
for (const issue of issues) {
|
|
@@ -1473,6 +1474,43 @@ var N8nValidator = class {
|
|
|
1473
1474
|
}
|
|
1474
1475
|
}
|
|
1475
1476
|
}
|
|
1477
|
+
// Rule 35 (WARN): email-sending node with no duplicate-prevention signal
|
|
1478
|
+
checkRule35(w, issues) {
|
|
1479
|
+
if (!Array.isArray(w.nodes)) return;
|
|
1480
|
+
const sendNodes = w.nodes.filter((node) => {
|
|
1481
|
+
if (node.type === "n8n-nodes-base.gmail") {
|
|
1482
|
+
const op = node.parameters?.["operation"];
|
|
1483
|
+
return !op || op === "send" || op === "sendEmail" || op === "reply";
|
|
1484
|
+
}
|
|
1485
|
+
return node.type === "n8n-nodes-base.emailSend" || node.type === "n8n-nodes-base.sendEmail";
|
|
1486
|
+
});
|
|
1487
|
+
if (sendNodes.length === 0) return;
|
|
1488
|
+
const workflowText = JSON.stringify(w).toLowerCase();
|
|
1489
|
+
const IDEMPOTENCY_SIGNALS = [
|
|
1490
|
+
"sent_at",
|
|
1491
|
+
"last_sent",
|
|
1492
|
+
"last_reminder",
|
|
1493
|
+
"processed_at",
|
|
1494
|
+
"already_sent",
|
|
1495
|
+
"email_sent",
|
|
1496
|
+
"notified_at",
|
|
1497
|
+
"reminder_sent",
|
|
1498
|
+
"contacted_at",
|
|
1499
|
+
"dedupe",
|
|
1500
|
+
"idempotent"
|
|
1501
|
+
];
|
|
1502
|
+
const hasIdempotencySignal = IDEMPOTENCY_SIGNALS.some((s) => workflowText.includes(s));
|
|
1503
|
+
if (!hasIdempotencySignal) {
|
|
1504
|
+
for (const node of sendNodes) {
|
|
1505
|
+
this.warn(
|
|
1506
|
+
issues,
|
|
1507
|
+
35,
|
|
1508
|
+
`Node "${node.name}" sends email but no duplicate-prevention signal detected \u2014 add a sent_at timestamp field, a prior-send IF check, or a deduplication key to avoid repeat sends`,
|
|
1509
|
+
node.id
|
|
1510
|
+
);
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1476
1514
|
// Rule 34 (WARN): webhook path contains spaces, starts with slash, or looks like a full URL
|
|
1477
1515
|
checkRule34(w, issues) {
|
|
1478
1516
|
if (!Array.isArray(w.nodes)) return;
|
|
@@ -2020,7 +2058,7 @@ Respond ONLY with a generate_workflow tool call. No prose. No markdown outside t
|
|
|
2020
2058
|
If the request is impossible or unclear, set the error field instead of generating a workflow.`;
|
|
2021
2059
|
|
|
2022
2060
|
// src/validation/rule-metadata.ts
|
|
2023
|
-
var VALIDATOR_RULE_IDS = Array.from({ length:
|
|
2061
|
+
var VALIDATOR_RULE_IDS = Array.from({ length: 35 }, (_, i) => i + 1);
|
|
2024
2062
|
var RULE_PIPELINE_STAGES = {
|
|
2025
2063
|
1: "node_generation",
|
|
2026
2064
|
2: "node_generation",
|
|
@@ -2055,7 +2093,8 @@ var RULE_PIPELINE_STAGES = {
|
|
|
2055
2093
|
31: "node_generation",
|
|
2056
2094
|
32: "node_generation",
|
|
2057
2095
|
33: "node_generation",
|
|
2058
|
-
34: "node_generation"
|
|
2096
|
+
34: "node_generation",
|
|
2097
|
+
35: "node_generation"
|
|
2059
2098
|
};
|
|
2060
2099
|
var RULE_EXAMPLES = {
|
|
2061
2100
|
17: {
|
|
@@ -2105,6 +2144,10 @@ var RULE_EXAMPLES = {
|
|
|
2105
2144
|
34: {
|
|
2106
2145
|
bad: '"path": "/my webhook"',
|
|
2107
2146
|
good: '"path": "my-webhook"'
|
|
2147
|
+
},
|
|
2148
|
+
35: {
|
|
2149
|
+
bad: '"type": "n8n-nodes-base.gmail", "parameters": { "operation": "send" } // no sent_at tracking',
|
|
2150
|
+
good: 'Add a Set node after send that writes "sent_at": "={{ $now }}" back to the sheet, or an IF node that checks sent_at before sending'
|
|
2108
2151
|
}
|
|
2109
2152
|
};
|
|
2110
2153
|
var RULE_MITIGATIONS = {
|
|
@@ -2141,7 +2184,8 @@ var RULE_MITIGATIONS = {
|
|
|
2141
2184
|
31: "Add at least one condition to the if node \u2014 conditions.conditions array must be non-empty",
|
|
2142
2185
|
32: "Add field assignments to the set node \u2014 assignments.assignments array must be non-empty for typeVersion 3.x",
|
|
2143
2186
|
33: "Add at least one schedule rule to scheduleTrigger \u2014 rule.interval array must have at least one entry",
|
|
2144
|
-
34: 'Webhook path must be a relative path without spaces, leading slashes, or protocol prefixes (e.g. "my-hook")'
|
|
2187
|
+
34: 'Webhook path must be a relative path without spaces, leading slashes, or protocol prefixes (e.g. "my-hook")',
|
|
2188
|
+
35: "Add duplicate-prevention to email-sending workflows: a sent_at timestamp field updated after each send, or an IF node that checks prior-send status before sending"
|
|
2145
2189
|
};
|
|
2146
2190
|
|
|
2147
2191
|
// src/generation/prompt-builder.ts
|