@slope-dev/slope 1.35.0 → 1.36.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/dist/cli/commands/loop.d.ts.map +1 -1
- package/dist/cli/commands/loop.js +5 -0
- package/dist/cli/commands/loop.js.map +1 -1
- package/dist/cli/commands/sprint.d.ts.map +1 -1
- package/dist/cli/commands/sprint.js +205 -3
- package/dist/cli/commands/sprint.js.map +1 -1
- package/dist/cli/commands/workflow.d.ts +2 -0
- package/dist/cli/commands/workflow.d.ts.map +1 -0
- package/dist/cli/commands/workflow.js +165 -0
- package/dist/cli/commands/workflow.js.map +1 -0
- package/dist/cli/index.js +7 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/loop/types.d.ts +4 -0
- package/dist/cli/loop/types.d.ts.map +1 -1
- package/dist/cli/loop/types.js.map +1 -1
- package/dist/cli/loop/workflow-adapter.d.ts +53 -0
- package/dist/cli/loop/workflow-adapter.d.ts.map +1 -0
- package/dist/cli/loop/workflow-adapter.js +123 -0
- package/dist/cli/loop/workflow-adapter.js.map +1 -0
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/cli/registry.js +8 -0
- package/dist/cli/registry.js.map +1 -1
- package/dist/core/guard.d.ts +1 -1
- package/dist/core/guard.d.ts.map +1 -1
- package/dist/core/guard.js +8 -0
- package/dist/core/guard.js.map +1 -1
- package/dist/core/index.d.ts +9 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +8 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/store.d.ts +25 -1
- package/dist/core/store.d.ts.map +1 -1
- package/dist/core/types.d.ts +34 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/workflow-engine.d.ts +89 -0
- package/dist/core/workflow-engine.d.ts.map +1 -0
- package/dist/core/workflow-engine.js +223 -0
- package/dist/core/workflow-engine.js.map +1 -0
- package/dist/core/workflow-loader.d.ts +21 -0
- package/dist/core/workflow-loader.d.ts.map +1 -0
- package/dist/core/workflow-loader.js +110 -0
- package/dist/core/workflow-loader.js.map +1 -0
- package/dist/core/workflow-validator.d.ts +19 -0
- package/dist/core/workflow-validator.d.ts.map +1 -0
- package/dist/core/workflow-validator.js +166 -0
- package/dist/core/workflow-validator.js.map +1 -0
- package/dist/core/workflow.d.ts +51 -0
- package/dist/core/workflow.d.ts.map +1 -0
- package/dist/core/workflow.js +190 -0
- package/dist/core/workflow.js.map +1 -0
- package/dist/mcp/index.d.ts +1 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +138 -2
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/index.test.js +10 -2
- package/dist/mcp/index.test.js.map +1 -1
- package/dist/mcp/registry.d.ts +1 -1
- package/dist/mcp/registry.d.ts.map +1 -1
- package/dist/mcp/registry.js +71 -0
- package/dist/mcp/registry.js.map +1 -1
- package/dist/store/index.d.ts +25 -1
- package/dist/store/index.d.ts.map +1 -1
- package/dist/store/index.js +144 -0
- package/dist/store/index.js.map +1 -1
- package/dist/store-pg/index.d.ts +25 -1
- package/dist/store-pg/index.d.ts.map +1 -1
- package/dist/store-pg/index.js +180 -0
- package/dist/store-pg/index.js.map +1 -1
- package/package.json +4 -2
- package/src/core/workflows/sprint-autonomous.yaml +59 -0
- package/src/core/workflows/sprint-lightweight.yaml +39 -0
- package/src/core/workflows/sprint-standard.yaml +77 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-loader.js","sourceRoot":"","sources":["../../src/core/workflow-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { WorkflowDefinition } from './workflow.js';
|
|
2
|
+
/** A single validation error or warning */
|
|
3
|
+
export interface ValidationIssue {
|
|
4
|
+
message: string;
|
|
5
|
+
/** Dot-path to the problematic element (e.g., "phases[0].steps[1]") */
|
|
6
|
+
path?: string;
|
|
7
|
+
}
|
|
8
|
+
/** Result of validating a workflow definition */
|
|
9
|
+
export interface WorkflowValidationResult {
|
|
10
|
+
valid: boolean;
|
|
11
|
+
errors: ValidationIssue[];
|
|
12
|
+
warnings: ValidationIssue[];
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Validate a parsed WorkflowDefinition for structural issues.
|
|
16
|
+
* Does NOT re-validate YAML parsing — assumes parseWorkflow() already succeeded.
|
|
17
|
+
*/
|
|
18
|
+
export declare function validateWorkflow(def: WorkflowDefinition): WorkflowValidationResult;
|
|
19
|
+
//# sourceMappingURL=workflow-validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-validator.d.ts","sourceRoot":"","sources":["../../src/core/workflow-validator.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAgB,MAAM,eAAe,CAAC;AAGtE,2CAA2C;AAC3C,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,iDAAiD;AACjD,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,kBAAkB,GAAG,wBAAwB,CA6HlF"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
// SLOPE — Workflow Validator
|
|
2
|
+
// Validates WorkflowDefinitions for structural correctness before execution.
|
|
3
|
+
import { VALID_STEP_TYPES } from './workflow.js';
|
|
4
|
+
/**
|
|
5
|
+
* Validate a parsed WorkflowDefinition for structural issues.
|
|
6
|
+
* Does NOT re-validate YAML parsing — assumes parseWorkflow() already succeeded.
|
|
7
|
+
*/
|
|
8
|
+
export function validateWorkflow(def) {
|
|
9
|
+
const errors = [];
|
|
10
|
+
const warnings = [];
|
|
11
|
+
// Version check
|
|
12
|
+
if (def.version !== '1') {
|
|
13
|
+
errors.push({ message: `Unsupported workflow version: "${def.version}" (expected "1")` });
|
|
14
|
+
}
|
|
15
|
+
// Name check
|
|
16
|
+
if (!def.name || def.name.trim().length === 0) {
|
|
17
|
+
errors.push({ message: 'Workflow name must be a non-empty string' });
|
|
18
|
+
}
|
|
19
|
+
// Collect all step IDs for uniqueness check
|
|
20
|
+
const allStepIds = new Map(); // step_id → phase_id
|
|
21
|
+
// Collect all variable references found in steps
|
|
22
|
+
const referencedVars = new Set();
|
|
23
|
+
const definedVars = new Set(Object.keys(def.variables ?? {}));
|
|
24
|
+
if (def.phases.length === 0) {
|
|
25
|
+
warnings.push({ message: 'Workflow has no phases' });
|
|
26
|
+
}
|
|
27
|
+
// Phase-level checks
|
|
28
|
+
const phaseIds = new Set();
|
|
29
|
+
for (let pi = 0; pi < def.phases.length; pi++) {
|
|
30
|
+
const phase = def.phases[pi];
|
|
31
|
+
const pPath = `phases[${pi}]`;
|
|
32
|
+
// Duplicate phase ID
|
|
33
|
+
if (phaseIds.has(phase.id)) {
|
|
34
|
+
errors.push({ message: `Duplicate phase ID: "${phase.id}"`, path: pPath });
|
|
35
|
+
}
|
|
36
|
+
phaseIds.add(phase.id);
|
|
37
|
+
// Empty steps
|
|
38
|
+
if (phase.steps.length === 0) {
|
|
39
|
+
warnings.push({ message: `Phase "${phase.id}" has no steps`, path: pPath });
|
|
40
|
+
}
|
|
41
|
+
// repeat_for variable reference
|
|
42
|
+
if (phase.repeat_for) {
|
|
43
|
+
referencedVars.add(phase.repeat_for);
|
|
44
|
+
if (definedVars.size > 0 && !definedVars.has(phase.repeat_for)) {
|
|
45
|
+
warnings.push({
|
|
46
|
+
message: `Phase "${phase.id}" references variable "${phase.repeat_for}" in repeat_for, but it is not defined in variables`,
|
|
47
|
+
path: `${pPath}.repeat_for`,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
// on_timeout only makes sense with repeat_for
|
|
51
|
+
if (phase.timeout_per_item && !phase.on_timeout) {
|
|
52
|
+
warnings.push({
|
|
53
|
+
message: `Phase "${phase.id}" has timeout_per_item but no on_timeout behavior`,
|
|
54
|
+
path: `${pPath}.on_timeout`,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
// on_timeout without repeat_for
|
|
60
|
+
if (phase.on_timeout) {
|
|
61
|
+
warnings.push({
|
|
62
|
+
message: `Phase "${phase.id}" has on_timeout but no repeat_for — on_timeout is ignored`,
|
|
63
|
+
path: `${pPath}.on_timeout`,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Step-level checks
|
|
68
|
+
for (let si = 0; si < phase.steps.length; si++) {
|
|
69
|
+
const step = phase.steps[si];
|
|
70
|
+
const sPath = `${pPath}.steps[${si}]`;
|
|
71
|
+
// Duplicate step ID across all phases
|
|
72
|
+
if (allStepIds.has(step.id)) {
|
|
73
|
+
errors.push({
|
|
74
|
+
message: `Duplicate step ID: "${step.id}" (also in phase "${allStepIds.get(step.id)}")`,
|
|
75
|
+
path: sPath,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
allStepIds.set(step.id, phase.id);
|
|
79
|
+
// Valid step type
|
|
80
|
+
if (!VALID_STEP_TYPES.has(step.type)) {
|
|
81
|
+
errors.push({
|
|
82
|
+
message: `Invalid step type: "${step.type}"`,
|
|
83
|
+
path: `${sPath}.type`,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
// Type-specific validation
|
|
87
|
+
validateStepByType(step, sPath, errors, warnings);
|
|
88
|
+
// blocks_next on terminal step is redundant
|
|
89
|
+
if (step.blocks_next && si === phase.steps.length - 1) {
|
|
90
|
+
warnings.push({
|
|
91
|
+
message: `Step "${step.id}" has blocks_next but is the last step in its phase — this is redundant`,
|
|
92
|
+
path: `${sPath}.blocks_next`,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
// Collect variable references from string fields
|
|
96
|
+
collectVarRefs(step.command, referencedVars);
|
|
97
|
+
collectVarRefs(step.prompt, referencedVars);
|
|
98
|
+
if (step.rules)
|
|
99
|
+
step.rules.forEach(r => collectVarRefs(r, referencedVars));
|
|
100
|
+
if (step.conditions)
|
|
101
|
+
step.conditions.forEach(c => collectVarRefs(c, referencedVars));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Warn about unreferenced variables
|
|
105
|
+
for (const varName of definedVars) {
|
|
106
|
+
if (!referencedVars.has(varName)) {
|
|
107
|
+
warnings.push({
|
|
108
|
+
message: `Variable "${varName}" is defined but never referenced`,
|
|
109
|
+
path: `variables.${varName}`,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
valid: errors.length === 0,
|
|
115
|
+
errors,
|
|
116
|
+
warnings,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/** Validate type-specific step requirements */
|
|
120
|
+
function validateStepByType(step, path, errors, warnings) {
|
|
121
|
+
switch (step.type) {
|
|
122
|
+
case 'command':
|
|
123
|
+
if (!step.command) {
|
|
124
|
+
errors.push({
|
|
125
|
+
message: `Command step "${step.id}" must have a "command" field`,
|
|
126
|
+
path: `${path}.command`,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
break;
|
|
130
|
+
case 'validation':
|
|
131
|
+
if (!step.conditions?.length && !step.command) {
|
|
132
|
+
warnings.push({
|
|
133
|
+
message: `Validation step "${step.id}" has no conditions or command — it will always pass`,
|
|
134
|
+
path,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
break;
|
|
138
|
+
case 'agent_input':
|
|
139
|
+
if (!step.required_fields?.length && !step.prompt) {
|
|
140
|
+
warnings.push({
|
|
141
|
+
message: `Agent input step "${step.id}" has no required_fields or prompt`,
|
|
142
|
+
path,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
break;
|
|
146
|
+
case 'agent_work':
|
|
147
|
+
if (!step.prompt && !step.rules?.length) {
|
|
148
|
+
warnings.push({
|
|
149
|
+
message: `Agent work step "${step.id}" has no prompt or rules — agent has no guidance`,
|
|
150
|
+
path,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/** Extract ${varName} references from a string */
|
|
157
|
+
function collectVarRefs(str, refs) {
|
|
158
|
+
if (!str)
|
|
159
|
+
return;
|
|
160
|
+
const pattern = /\$\{([a-zA-Z_][a-zA-Z0-9_]*)\}/g;
|
|
161
|
+
let match;
|
|
162
|
+
while ((match = pattern.exec(str)) !== null) {
|
|
163
|
+
refs.add(match[1]);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=workflow-validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-validator.js","sourceRoot":"","sources":["../../src/core/workflow-validator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/** Variable definition for workflow parameterization */
|
|
2
|
+
export interface WorkflowVariable {
|
|
3
|
+
required?: boolean;
|
|
4
|
+
type?: 'string' | 'integer' | 'array';
|
|
5
|
+
pattern?: string;
|
|
6
|
+
default?: string;
|
|
7
|
+
}
|
|
8
|
+
/** A single step within a workflow phase */
|
|
9
|
+
export interface WorkflowStep {
|
|
10
|
+
id: string;
|
|
11
|
+
type: 'command' | 'validation' | 'agent_input' | 'agent_work';
|
|
12
|
+
prompt?: string;
|
|
13
|
+
command?: string;
|
|
14
|
+
checkpoint?: string;
|
|
15
|
+
blocks_next?: boolean;
|
|
16
|
+
rules?: string[];
|
|
17
|
+
required_fields?: string[];
|
|
18
|
+
/** Validation conditions (for type=validation) */
|
|
19
|
+
conditions?: string[];
|
|
20
|
+
}
|
|
21
|
+
/** A phase containing ordered steps */
|
|
22
|
+
export interface WorkflowPhase {
|
|
23
|
+
id: string;
|
|
24
|
+
steps: WorkflowStep[];
|
|
25
|
+
/** Variable name containing array to iterate over */
|
|
26
|
+
repeat_for?: string;
|
|
27
|
+
/** Timeout in seconds for each repeated item */
|
|
28
|
+
timeout_per_item?: number;
|
|
29
|
+
/** Behavior when a repeated item times out */
|
|
30
|
+
on_timeout?: 'fail' | 'log_blocker_and_skip';
|
|
31
|
+
}
|
|
32
|
+
/** Top-level workflow definition */
|
|
33
|
+
export interface WorkflowDefinition {
|
|
34
|
+
name: string;
|
|
35
|
+
version: string;
|
|
36
|
+
description?: string;
|
|
37
|
+
variables?: Record<string, WorkflowVariable>;
|
|
38
|
+
phases: WorkflowPhase[];
|
|
39
|
+
}
|
|
40
|
+
/** Parse a YAML string into a WorkflowDefinition. Throws on invalid structure. */
|
|
41
|
+
export declare function parseWorkflow(yaml: string): WorkflowDefinition;
|
|
42
|
+
/** Valid step types for workflow definitions. Shared with the validator. */
|
|
43
|
+
export declare const VALID_STEP_TYPES: Set<string>;
|
|
44
|
+
/**
|
|
45
|
+
* Resolve `${varName}` references in all string values of a workflow definition.
|
|
46
|
+
* - Top-level string keys only (no nesting like `${x.y}`)
|
|
47
|
+
* - Missing variable at resolve time → error
|
|
48
|
+
* - Escaped `\${literal}` → `${literal}`
|
|
49
|
+
*/
|
|
50
|
+
export declare function resolveVariables(def: WorkflowDefinition, vars: Record<string, string>): WorkflowDefinition;
|
|
51
|
+
//# sourceMappingURL=workflow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../../src/core/workflow.ts"],"names":[],"mappings":"AAOA,wDAAwD;AACxD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,4CAA4C;AAC5C,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,SAAS,GAAG,YAAY,GAAG,aAAa,GAAG,YAAY,CAAC;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,uCAAuC;AACvC,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,GAAG,sBAAsB,CAAC;CAC9C;AAED,oCAAoC;AACpC,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC7C,MAAM,EAAE,aAAa,EAAE,CAAC;CACzB;AAID,kFAAkF;AAClF,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,CA0C9D;AAuBD,4EAA4E;AAC5E,eAAO,MAAM,gBAAgB,aAAkE,CAAC;AAoEhG;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,kBAAkB,EACvB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC3B,kBAAkB,CA0CpB"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
// SLOPE — Workflow Definition Types & YAML Parser
|
|
2
|
+
// Parses YAML 1.2 workflow definitions into typed structures for the workflow engine.
|
|
3
|
+
import { parseDocument } from 'yaml';
|
|
4
|
+
// --- Parser ---
|
|
5
|
+
/** Parse a YAML string into a WorkflowDefinition. Throws on invalid structure. */
|
|
6
|
+
export function parseWorkflow(yaml) {
|
|
7
|
+
const doc = parseDocument(yaml, { schema: 'core' });
|
|
8
|
+
if (doc.errors.length > 0) {
|
|
9
|
+
throw new Error(`YAML parse error: ${doc.errors[0].message}`);
|
|
10
|
+
}
|
|
11
|
+
const raw = doc.toJS();
|
|
12
|
+
if (!raw || typeof raw !== 'object') {
|
|
13
|
+
throw new Error('Workflow must be a YAML mapping');
|
|
14
|
+
}
|
|
15
|
+
// Required fields
|
|
16
|
+
if (!raw.name || typeof raw.name !== 'string') {
|
|
17
|
+
throw new Error('Workflow must have a string "name" field');
|
|
18
|
+
}
|
|
19
|
+
if (!raw.version || typeof raw.version !== 'string') {
|
|
20
|
+
throw new Error('Workflow must have a string "version" field');
|
|
21
|
+
}
|
|
22
|
+
if (!Array.isArray(raw.phases)) {
|
|
23
|
+
throw new Error('Workflow must have a "phases" array');
|
|
24
|
+
}
|
|
25
|
+
// Parse variables
|
|
26
|
+
const variables = raw.variables && typeof raw.variables === 'object' && !Array.isArray(raw.variables)
|
|
27
|
+
? parseVariables(raw.variables)
|
|
28
|
+
: undefined;
|
|
29
|
+
// Parse phases
|
|
30
|
+
const phases = raw.phases.map((p, i) => parsePhase(p, i));
|
|
31
|
+
return {
|
|
32
|
+
name: raw.name,
|
|
33
|
+
version: raw.version,
|
|
34
|
+
description: typeof raw.description === 'string' ? raw.description : undefined,
|
|
35
|
+
variables,
|
|
36
|
+
phases,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function parseVariables(raw) {
|
|
40
|
+
const result = {};
|
|
41
|
+
for (const [key, val] of Object.entries(raw)) {
|
|
42
|
+
if (typeof val !== 'object' || val === null || Array.isArray(val)) {
|
|
43
|
+
throw new Error(`Variable "${key}" must be a mapping`);
|
|
44
|
+
}
|
|
45
|
+
const v = val;
|
|
46
|
+
result[key] = {
|
|
47
|
+
required: typeof v.required === 'boolean' ? v.required : undefined,
|
|
48
|
+
type: isVariableType(v.type) ? v.type : undefined,
|
|
49
|
+
pattern: typeof v.pattern === 'string' ? v.pattern : undefined,
|
|
50
|
+
default: v.default !== undefined ? String(v.default) : undefined,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
function isVariableType(val) {
|
|
56
|
+
return val === 'string' || val === 'integer' || val === 'array';
|
|
57
|
+
}
|
|
58
|
+
/** Valid step types for workflow definitions. Shared with the validator. */
|
|
59
|
+
export const VALID_STEP_TYPES = new Set(['command', 'validation', 'agent_input', 'agent_work']);
|
|
60
|
+
function parsePhase(raw, index) {
|
|
61
|
+
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
|
|
62
|
+
throw new Error(`Phase at index ${index} must be a mapping`);
|
|
63
|
+
}
|
|
64
|
+
const p = raw;
|
|
65
|
+
if (!p.id || typeof p.id !== 'string') {
|
|
66
|
+
throw new Error(`Phase at index ${index} must have a string "id"`);
|
|
67
|
+
}
|
|
68
|
+
if (!Array.isArray(p.steps)) {
|
|
69
|
+
throw new Error(`Phase "${p.id}" must have a "steps" array`);
|
|
70
|
+
}
|
|
71
|
+
const steps = p.steps.map((s, si) => parseStep(s, p.id, si));
|
|
72
|
+
return {
|
|
73
|
+
id: p.id,
|
|
74
|
+
steps,
|
|
75
|
+
repeat_for: typeof p.repeat_for === 'string' ? p.repeat_for : undefined,
|
|
76
|
+
timeout_per_item: typeof p.timeout_per_item === 'number' ? p.timeout_per_item : undefined,
|
|
77
|
+
on_timeout: p.on_timeout === 'fail' || p.on_timeout === 'log_blocker_and_skip'
|
|
78
|
+
? p.on_timeout
|
|
79
|
+
: undefined,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
function parseStep(raw, phaseId, index) {
|
|
83
|
+
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
|
|
84
|
+
throw new Error(`Step at index ${index} in phase "${phaseId}" must be a mapping`);
|
|
85
|
+
}
|
|
86
|
+
const s = raw;
|
|
87
|
+
if (!s.id || typeof s.id !== 'string') {
|
|
88
|
+
throw new Error(`Step at index ${index} in phase "${phaseId}" must have a string "id"`);
|
|
89
|
+
}
|
|
90
|
+
if (!s.type || typeof s.type !== 'string' || !VALID_STEP_TYPES.has(s.type)) {
|
|
91
|
+
throw new Error(`Step "${s.id}" in phase "${phaseId}" must have a valid "type" (command|validation|agent_input|agent_work)`);
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
id: s.id,
|
|
95
|
+
type: s.type,
|
|
96
|
+
prompt: typeof s.prompt === 'string' ? s.prompt : undefined,
|
|
97
|
+
command: typeof s.command === 'string' ? s.command : undefined,
|
|
98
|
+
checkpoint: typeof s.checkpoint === 'string' ? s.checkpoint : undefined,
|
|
99
|
+
blocks_next: typeof s.blocks_next === 'boolean' ? s.blocks_next : undefined,
|
|
100
|
+
rules: Array.isArray(s.rules) ? s.rules.map(r => String(r)) : undefined,
|
|
101
|
+
required_fields: Array.isArray(s.required_fields)
|
|
102
|
+
? s.required_fields.map(r => String(r))
|
|
103
|
+
: undefined,
|
|
104
|
+
conditions: Array.isArray(s.conditions)
|
|
105
|
+
? s.conditions.map(c => String(c))
|
|
106
|
+
: undefined,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
// --- Variable Interpolation ---
|
|
110
|
+
/**
|
|
111
|
+
* Resolve `${varName}` references in all string values of a workflow definition.
|
|
112
|
+
* - Top-level string keys only (no nesting like `${x.y}`)
|
|
113
|
+
* - Missing variable at resolve time → error
|
|
114
|
+
* - Escaped `\${literal}` → `${literal}`
|
|
115
|
+
*/
|
|
116
|
+
export function resolveVariables(def, vars) {
|
|
117
|
+
// Validate all required variables are provided
|
|
118
|
+
if (def.variables) {
|
|
119
|
+
for (const [name, spec] of Object.entries(def.variables)) {
|
|
120
|
+
if (spec.required && !(name in vars) && spec.default === undefined) {
|
|
121
|
+
throw new Error(`Required variable "${name}" not provided`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// Build resolved vars: provided values + defaults
|
|
126
|
+
const resolved = {};
|
|
127
|
+
if (def.variables) {
|
|
128
|
+
for (const [name, spec] of Object.entries(def.variables)) {
|
|
129
|
+
if (name in vars) {
|
|
130
|
+
resolved[name] = vars[name];
|
|
131
|
+
}
|
|
132
|
+
else if (spec.default !== undefined) {
|
|
133
|
+
resolved[name] = spec.default;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// Also include any extra vars not in the schema
|
|
138
|
+
for (const [name, val] of Object.entries(vars)) {
|
|
139
|
+
if (!(name in resolved)) {
|
|
140
|
+
resolved[name] = val;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// Validate patterns
|
|
144
|
+
if (def.variables) {
|
|
145
|
+
for (const [name, spec] of Object.entries(def.variables)) {
|
|
146
|
+
if (spec.pattern && name in resolved) {
|
|
147
|
+
const re = new RegExp(spec.pattern);
|
|
148
|
+
if (!re.test(resolved[name])) {
|
|
149
|
+
throw new Error(`Variable "${name}" value "${resolved[name]}" does not match pattern "${spec.pattern}"`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// Deep-clone and interpolate all string values (avoids JSON.stringify escape issues)
|
|
155
|
+
return deepInterpolate(def, resolved);
|
|
156
|
+
}
|
|
157
|
+
/** Recursively walk a value, interpolating ${var} in all strings. */
|
|
158
|
+
function deepInterpolate(value, vars) {
|
|
159
|
+
if (typeof value === 'string') {
|
|
160
|
+
return interpolateString(value, vars);
|
|
161
|
+
}
|
|
162
|
+
if (Array.isArray(value)) {
|
|
163
|
+
return value.map(item => deepInterpolate(item, vars));
|
|
164
|
+
}
|
|
165
|
+
if (value !== null && typeof value === 'object') {
|
|
166
|
+
const result = {};
|
|
167
|
+
for (const [key, val] of Object.entries(value)) {
|
|
168
|
+
result[key] = deepInterpolate(val, vars);
|
|
169
|
+
}
|
|
170
|
+
return result;
|
|
171
|
+
}
|
|
172
|
+
return value;
|
|
173
|
+
}
|
|
174
|
+
/** Interpolate ${var} references in a string. Throws on unresolved variables. */
|
|
175
|
+
function interpolateString(str, vars) {
|
|
176
|
+
// Replace escaped \${ with a placeholder, then restore after interpolation
|
|
177
|
+
const PLACEHOLDER = '\x00ESCAPED_DOLLAR\x00';
|
|
178
|
+
let result = str.replace(/\\\$\{/g, PLACEHOLDER);
|
|
179
|
+
// Find and replace ${varName} references
|
|
180
|
+
result = result.replace(/\$\{([a-zA-Z_][a-zA-Z0-9_]*)\}/g, (_match, name) => {
|
|
181
|
+
if (!(name in vars)) {
|
|
182
|
+
throw new Error(`Unresolved variable reference: \${${name}}`);
|
|
183
|
+
}
|
|
184
|
+
return vars[name];
|
|
185
|
+
});
|
|
186
|
+
// Restore escaped references as literal ${
|
|
187
|
+
result = result.replaceAll(PLACEHOLDER, '${');
|
|
188
|
+
return result;
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=workflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow.js","sourceRoot":"","sources":["../../src/core/workflow.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
3
|
import type { SlopeStore, SlopeConfig } from '../core/index.js';
|
|
4
4
|
/** Tool names exposed by this MCP server (for tests and tool discovery). */
|
|
5
|
-
export declare const SLOPE_MCP_TOOL_NAMES: readonly ["search", "execute", "context_search", "session_status", "acquire_claim", "check_conflicts", "store_status", "testing_session_start", "testing_session_finding", "testing_session_end", "testing_session_status", "testing_plan_status"];
|
|
5
|
+
export declare const SLOPE_MCP_TOOL_NAMES: readonly ["search", "execute", "context_search", "session_status", "acquire_claim", "check_conflicts", "store_status", "testing_session_start", "testing_session_finding", "testing_session_end", "testing_session_status", "testing_plan_status", "workflow_next", "workflow_complete", "workflow_status"];
|
|
6
6
|
/** Detection results for hook/settings activation status. */
|
|
7
7
|
export interface SetupHints {
|
|
8
8
|
guardsInstalled: boolean;
|
package/dist/mcp/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":";AAwBA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAMhE,4EAA4E;AAC5E,eAAO,MAAM,oBAAoB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":";AAwBA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAMhE,4EAA4E;AAC5E,eAAO,MAAM,oBAAoB,6SAA8S,CAAC;AAEhV,6DAA6D;AAC7D,MAAM,WAAW,UAAU;IACzB,eAAe,EAAE,OAAO,CAAC;IACzB,uBAAuB,EAAE,OAAO,CAAC;IACjC,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AAED,0EAA0E;AAC1E,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,UAAU,CAkChE;AAED,6EAA6E;AAC7E,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CA+B/D;AAED,wBAAgB,sBAAsB,CAAC,KAAK,CAAC,EAAE,UAAU,EAAE,UAAU,CAAC,EAAE,UAAU,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CA6yBvI"}
|
package/dist/mcp/index.js
CHANGED
|
@@ -27,10 +27,10 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
|
|
|
27
27
|
import { z } from 'zod';
|
|
28
28
|
import { SLOPE_REGISTRY, SLOPE_TYPES } from './registry.js';
|
|
29
29
|
import { runInSandbox } from './sandbox.js';
|
|
30
|
-
import { checkConflicts, loadFlows, checkFlowStaleness, checkStoreHealth, METAPHOR_SCHEMA, listMetaphors, buildInterviewContext, generateInterviewSteps, loadConfig, parseTestPlan, getAreasNeedingTest, hasEmbeddingSupport, embed, deduplicateByFile, formatContextForAgent } from '../core/index.js';
|
|
30
|
+
import { checkConflicts, loadFlows, checkFlowStaleness, checkStoreHealth, METAPHOR_SCHEMA, listMetaphors, buildInterviewContext, generateInterviewSteps, loadConfig, parseTestPlan, getAreasNeedingTest, hasEmbeddingSupport, embed, deduplicateByFile, formatContextForAgent, WorkflowEngine, loadWorkflow, resolveVariables } from '../core/index.js';
|
|
31
31
|
import { gaming } from '../core/metaphors/gaming.js';
|
|
32
32
|
/** Tool names exposed by this MCP server (for tests and tool discovery). */
|
|
33
|
-
export const SLOPE_MCP_TOOL_NAMES = ['search', 'execute', 'context_search', 'session_status', 'acquire_claim', 'check_conflicts', 'store_status', 'testing_session_start', 'testing_session_finding', 'testing_session_end', 'testing_session_status', 'testing_plan_status'];
|
|
33
|
+
export const SLOPE_MCP_TOOL_NAMES = ['search', 'execute', 'context_search', 'session_status', 'acquire_claim', 'check_conflicts', 'store_status', 'testing_session_start', 'testing_session_finding', 'testing_session_end', 'testing_session_status', 'testing_plan_status', 'workflow_next', 'workflow_complete', 'workflow_status'];
|
|
34
34
|
/** Detect which SLOPE hooks and settings are activated in the project. */
|
|
35
35
|
export function detectSetupHints(projectRoot) {
|
|
36
36
|
const hints = {
|
|
@@ -614,6 +614,142 @@ export function createSlopeToolsServer(store, setupHints, storeType, config) {
|
|
|
614
614
|
};
|
|
615
615
|
return { content: [{ type: 'text', text: JSON.stringify(response, null, 2) }] };
|
|
616
616
|
});
|
|
617
|
+
// --- Workflow Tools ---
|
|
618
|
+
/** Resolve project root, falling back to cwd */
|
|
619
|
+
function safeProjectRoot() {
|
|
620
|
+
try {
|
|
621
|
+
return findProjectRoot(process.cwd());
|
|
622
|
+
}
|
|
623
|
+
catch {
|
|
624
|
+
return process.cwd();
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
const workflowEngine = new WorkflowEngine();
|
|
628
|
+
server.tool('workflow_next', 'Get the next step in a workflow execution. Returns the current step to execute, or signals completion.', {
|
|
629
|
+
execution_id: z.string().optional().describe('Workflow execution ID'),
|
|
630
|
+
session_id: z.string().optional().describe('Session ID to find active execution'),
|
|
631
|
+
}, async ({ execution_id, session_id }) => {
|
|
632
|
+
try {
|
|
633
|
+
let execId = execution_id;
|
|
634
|
+
// Fallback: find execution by session
|
|
635
|
+
if (!execId && session_id) {
|
|
636
|
+
const executions = await store.listExecutions({ status: 'running' });
|
|
637
|
+
const match = executions.find(e => e.session_id === session_id);
|
|
638
|
+
if (!match) {
|
|
639
|
+
return { content: [{ type: 'text', text: JSON.stringify({ error: `No active workflow execution found for session "${session_id}"` }) }], isError: true };
|
|
640
|
+
}
|
|
641
|
+
execId = match.id;
|
|
642
|
+
}
|
|
643
|
+
if (!execId) {
|
|
644
|
+
return { content: [{ type: 'text', text: JSON.stringify({ error: 'Either execution_id or session_id is required' }) }], isError: true };
|
|
645
|
+
}
|
|
646
|
+
const execution = await store.getExecution(execId);
|
|
647
|
+
if (!execution) {
|
|
648
|
+
return { content: [{ type: 'text', text: JSON.stringify({ error: `Execution "${execId}" not found` }) }], isError: true };
|
|
649
|
+
}
|
|
650
|
+
// Load and resolve the workflow definition
|
|
651
|
+
const def = resolveVariables(loadWorkflow(execution.workflow_name, safeProjectRoot()), execution.variables);
|
|
652
|
+
const next = await workflowEngine.next(execId, def, store);
|
|
653
|
+
return {
|
|
654
|
+
content: [{
|
|
655
|
+
type: 'text',
|
|
656
|
+
text: JSON.stringify({
|
|
657
|
+
execution_id: execId,
|
|
658
|
+
...next,
|
|
659
|
+
}, null, 2),
|
|
660
|
+
}],
|
|
661
|
+
};
|
|
662
|
+
}
|
|
663
|
+
catch (err) {
|
|
664
|
+
return { content: [{ type: 'text', text: JSON.stringify({ error: err.message }) }], isError: true };
|
|
665
|
+
}
|
|
666
|
+
});
|
|
667
|
+
server.tool('workflow_complete', 'Complete the current step in a workflow execution and advance to the next step.', {
|
|
668
|
+
execution_id: z.string().describe('Workflow execution ID'),
|
|
669
|
+
step_id: z.string().describe('Step ID being completed'),
|
|
670
|
+
output: z.record(z.unknown()).optional().describe('Step output data'),
|
|
671
|
+
exit_code: z.number().optional().describe('Exit code for command steps'),
|
|
672
|
+
}, async ({ execution_id, step_id, output, exit_code }) => {
|
|
673
|
+
try {
|
|
674
|
+
const execution = await store.getExecution(execution_id);
|
|
675
|
+
if (!execution) {
|
|
676
|
+
return { content: [{ type: 'text', text: JSON.stringify({ error: `Execution "${execution_id}" not found` }) }], isError: true };
|
|
677
|
+
}
|
|
678
|
+
const def = resolveVariables(loadWorkflow(execution.workflow_name, safeProjectRoot()), execution.variables);
|
|
679
|
+
const result = await workflowEngine.complete(execution_id, step_id, { output: output, exit_code }, def, store);
|
|
680
|
+
return {
|
|
681
|
+
content: [{
|
|
682
|
+
type: 'text',
|
|
683
|
+
text: JSON.stringify({
|
|
684
|
+
execution_id,
|
|
685
|
+
...result,
|
|
686
|
+
}, null, 2),
|
|
687
|
+
}],
|
|
688
|
+
};
|
|
689
|
+
}
|
|
690
|
+
catch (err) {
|
|
691
|
+
return { content: [{ type: 'text', text: JSON.stringify({ error: err.message }) }], isError: true };
|
|
692
|
+
}
|
|
693
|
+
});
|
|
694
|
+
server.tool('workflow_status', 'Show the status of a workflow execution with progress summary.', {
|
|
695
|
+
execution_id: z.string().optional().describe('Specific execution ID, or omit for all active executions'),
|
|
696
|
+
}, async ({ execution_id }) => {
|
|
697
|
+
try {
|
|
698
|
+
if (execution_id) {
|
|
699
|
+
const execution = await store.getExecution(execution_id);
|
|
700
|
+
if (!execution) {
|
|
701
|
+
return { content: [{ type: 'text', text: JSON.stringify({ error: `Execution "${execution_id}" not found` }) }], isError: true };
|
|
702
|
+
}
|
|
703
|
+
// Load def to compute total steps (accounting for repeat_for multiplier)
|
|
704
|
+
let totalSteps = 0;
|
|
705
|
+
try {
|
|
706
|
+
const def = resolveVariables(loadWorkflow(execution.workflow_name, safeProjectRoot()), execution.variables);
|
|
707
|
+
totalSteps = def.phases.reduce((sum, p) => {
|
|
708
|
+
const stepCount = p.steps.length;
|
|
709
|
+
if (p.repeat_for && execution.variables[p.repeat_for]) {
|
|
710
|
+
const items = execution.variables[p.repeat_for].split(',').filter(Boolean);
|
|
711
|
+
return sum + stepCount * items.length;
|
|
712
|
+
}
|
|
713
|
+
return sum + stepCount;
|
|
714
|
+
}, 0);
|
|
715
|
+
}
|
|
716
|
+
catch { /* def not available — ok */ }
|
|
717
|
+
return {
|
|
718
|
+
content: [{
|
|
719
|
+
type: 'text',
|
|
720
|
+
text: JSON.stringify({
|
|
721
|
+
...execution,
|
|
722
|
+
progress: {
|
|
723
|
+
completed_steps: execution.completed_steps.length,
|
|
724
|
+
total_steps: totalSteps || undefined,
|
|
725
|
+
},
|
|
726
|
+
}, null, 2),
|
|
727
|
+
}],
|
|
728
|
+
};
|
|
729
|
+
}
|
|
730
|
+
// List all active executions
|
|
731
|
+
const active = await store.listExecutions({ status: 'running' });
|
|
732
|
+
return {
|
|
733
|
+
content: [{
|
|
734
|
+
type: 'text',
|
|
735
|
+
text: JSON.stringify({
|
|
736
|
+
active_executions: active.map(e => ({
|
|
737
|
+
id: e.id,
|
|
738
|
+
workflow_name: e.workflow_name,
|
|
739
|
+
sprint_id: e.sprint_id,
|
|
740
|
+
current_phase: e.current_phase,
|
|
741
|
+
current_step: e.current_step,
|
|
742
|
+
completed_steps: e.completed_steps.length,
|
|
743
|
+
started_at: e.started_at,
|
|
744
|
+
})),
|
|
745
|
+
}, null, 2),
|
|
746
|
+
}],
|
|
747
|
+
};
|
|
748
|
+
}
|
|
749
|
+
catch (err) {
|
|
750
|
+
return { content: [{ type: 'text', text: JSON.stringify({ error: err.message }) }], isError: true };
|
|
751
|
+
}
|
|
752
|
+
});
|
|
617
753
|
}
|
|
618
754
|
return server;
|
|
619
755
|
}
|