@ebowwa/workflows 0.1.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 +257 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4641 -0
- package/dist/mcp/index.d.ts +57 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +17545 -0
- package/dist/runner.d.ts +62 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/sandbox.d.ts +67 -0
- package/dist/sandbox.d.ts.map +1 -0
- package/dist/scheduler.d.ts +93 -0
- package/dist/scheduler.d.ts.map +1 -0
- package/dist/types.d.ts +823 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +62 -0
- package/src/index.ts +72 -0
- package/src/mcp/index.ts +572 -0
- package/src/runner.ts +308 -0
- package/src/sandbox.ts +305 -0
- package/src/scheduler.ts +287 -0
- package/src/types.ts +218 -0
package/README.md
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
# @ebowwa/workflows
|
|
2
|
+
|
|
3
|
+
CI/CD Workflow System with process-level isolation, job scheduling, and real-time GUI support.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Process-level isolation** - Each step runs in an isolated process
|
|
8
|
+
- **Job dependencies** - Define job ordering with `needs` field
|
|
9
|
+
- **Parallel execution** - Jobs run in parallel when dependencies allow
|
|
10
|
+
- **Real-time streaming** - WebSocket-based log streaming
|
|
11
|
+
- **MCP integration** - Control workflows via Model Context Protocol
|
|
12
|
+
- **Type-safe** - Full TypeScript support with Zod validation
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
bun add @ebowwa/workflows
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
### Define a Workflow
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import { WorkflowSchema, createRunner } from '@ebowwa/workflows';
|
|
26
|
+
|
|
27
|
+
const workflow = WorkflowSchema.parse({
|
|
28
|
+
id: 'build-test',
|
|
29
|
+
name: 'Build and Test',
|
|
30
|
+
triggers: [{ type: 'manual' }],
|
|
31
|
+
jobs: {
|
|
32
|
+
build: {
|
|
33
|
+
name: 'Build',
|
|
34
|
+
runsOn: 'bun',
|
|
35
|
+
steps: [
|
|
36
|
+
{ name: 'Install', run: 'bun install' },
|
|
37
|
+
{ name: 'Build', run: 'bun run build' },
|
|
38
|
+
],
|
|
39
|
+
},
|
|
40
|
+
test: {
|
|
41
|
+
name: 'Test',
|
|
42
|
+
runsOn: 'bun',
|
|
43
|
+
needs: ['build'],
|
|
44
|
+
steps: [
|
|
45
|
+
{ name: 'Test', run: 'bun test' },
|
|
46
|
+
],
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Run the Workflow
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
const runner = createRunner();
|
|
56
|
+
|
|
57
|
+
// Listen for events
|
|
58
|
+
runner.on('event', (event) => {
|
|
59
|
+
console.log(`[${event.type}] ${event.runId}`);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
runner.on('log', (log) => {
|
|
63
|
+
process.stdout.write(log.content);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// Execute
|
|
67
|
+
const run = await runner.runWorkflow(workflow);
|
|
68
|
+
console.log(`Workflow ${run.status}`);
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## API Reference
|
|
72
|
+
|
|
73
|
+
### Types
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
interface Workflow {
|
|
77
|
+
id: string;
|
|
78
|
+
name: string;
|
|
79
|
+
triggers: Trigger[];
|
|
80
|
+
jobs: Record<string, Job>;
|
|
81
|
+
env?: Record<string, string>;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
interface Job {
|
|
85
|
+
name: string;
|
|
86
|
+
runsOn: 'bun' | 'tsx' | 'rust' | 'bash';
|
|
87
|
+
steps: Step[];
|
|
88
|
+
needs?: string[]; // Job dependencies
|
|
89
|
+
env?: Record<string, string>;
|
|
90
|
+
timeout?: number;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
interface Step {
|
|
94
|
+
id?: string;
|
|
95
|
+
name?: string;
|
|
96
|
+
run: string;
|
|
97
|
+
cwd?: string;
|
|
98
|
+
env?: Record<string, string>;
|
|
99
|
+
condition?: string; // 'success()', 'failure()', 'always()'
|
|
100
|
+
retry?: number;
|
|
101
|
+
timeout?: number;
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Runner
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
import { createRunner, WorkflowRunner } from '@ebowwa/workflows';
|
|
109
|
+
|
|
110
|
+
const runner = createRunner({
|
|
111
|
+
workspace: '/path/to/workspace',
|
|
112
|
+
env: { NODE_ENV: 'production' },
|
|
113
|
+
maxConcurrentJobs: 4,
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
// Run workflow
|
|
117
|
+
const run = await runner.runWorkflow(workflow, {
|
|
118
|
+
trigger: { type: 'manual' },
|
|
119
|
+
env: { CUSTOM_VAR: 'value' },
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// Cancel run
|
|
123
|
+
runner.cancelRun(run.id);
|
|
124
|
+
|
|
125
|
+
// Events
|
|
126
|
+
runner.on('event', (event) => { /* ... */ });
|
|
127
|
+
runner.on('log', (log) => { /* ... */ });
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## MCP Server
|
|
131
|
+
|
|
132
|
+
Run the MCP server for LLM integration:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
bun run @ebowwa/workflows/mcp
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### MCP Tools
|
|
139
|
+
|
|
140
|
+
| Tool | Description |
|
|
141
|
+
|------|-------------|
|
|
142
|
+
| `workflow_list` | List all workflows |
|
|
143
|
+
| `workflow_create` | Create a new workflow |
|
|
144
|
+
| `workflow_get` | Get workflow details |
|
|
145
|
+
| `workflow_delete` | Delete a workflow |
|
|
146
|
+
| `workflow_run` | Trigger a workflow run |
|
|
147
|
+
| `run_list` | List workflow runs |
|
|
148
|
+
| `run_get` | Get run details |
|
|
149
|
+
| `run_cancel` | Cancel a running workflow |
|
|
150
|
+
| `run_logs` | Get run logs |
|
|
151
|
+
|
|
152
|
+
## REST API Server
|
|
153
|
+
|
|
154
|
+
Run the API server with WebSocket support:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
bun run server/index.ts
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Endpoints
|
|
161
|
+
|
|
162
|
+
| Method | Path | Description |
|
|
163
|
+
|--------|------|-------------|
|
|
164
|
+
| GET | `/api/workflows` | List workflows |
|
|
165
|
+
| POST | `/api/workflows` | Create workflow |
|
|
166
|
+
| GET | `/api/workflows/:id` | Get workflow |
|
|
167
|
+
| DELETE | `/api/workflows/:id` | Delete workflow |
|
|
168
|
+
| POST | `/api/workflows/:id/run` | Trigger run |
|
|
169
|
+
| GET | `/api/runs` | List runs |
|
|
170
|
+
| GET | `/api/runs/:id` | Get run |
|
|
171
|
+
| DELETE | `/api/runs/:id` | Cancel run |
|
|
172
|
+
| WS | `/ws/:runId` | Real-time logs |
|
|
173
|
+
|
|
174
|
+
### WebSocket Protocol
|
|
175
|
+
|
|
176
|
+
**Server → Client:**
|
|
177
|
+
```typescript
|
|
178
|
+
type ServerMessage =
|
|
179
|
+
| { type: 'job_started'; jobId: string }
|
|
180
|
+
| { type: 'step_started'; jobId: string; stepId: string }
|
|
181
|
+
| { type: 'log'; jobId: string; stepId: string; content: string; stream: 'stdout' | 'stderr' }
|
|
182
|
+
| { type: 'step_finished'; jobId: string; stepId: string; exitCode: number; duration: number }
|
|
183
|
+
| { type: 'job_finished'; jobId: string; status: string }
|
|
184
|
+
| { type: 'workflow_finished'; status: string };
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**Client → Server:**
|
|
188
|
+
```typescript
|
|
189
|
+
type ClientMessage =
|
|
190
|
+
| { type: 'subscribe'; runId: string }
|
|
191
|
+
| { type: 'cancel' };
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Example: Complete Pipeline
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
import { WorkflowSchema, createRunner } from '@ebowwa/workflows';
|
|
198
|
+
|
|
199
|
+
const pipeline = WorkflowSchema.parse({
|
|
200
|
+
id: 'full-pipeline',
|
|
201
|
+
name: 'Full CI/CD Pipeline',
|
|
202
|
+
triggers: [
|
|
203
|
+
{ type: 'git', events: ['push', 'pr'] },
|
|
204
|
+
],
|
|
205
|
+
env: {
|
|
206
|
+
NODE_ENV: 'production',
|
|
207
|
+
},
|
|
208
|
+
jobs: {
|
|
209
|
+
install: {
|
|
210
|
+
name: 'Install Dependencies',
|
|
211
|
+
runsOn: 'bun',
|
|
212
|
+
steps: [
|
|
213
|
+
{ name: 'Install', run: 'bun install --frozen-lockfile' },
|
|
214
|
+
],
|
|
215
|
+
},
|
|
216
|
+
lint: {
|
|
217
|
+
name: 'Lint',
|
|
218
|
+
runsOn: 'bun',
|
|
219
|
+
needs: ['install'],
|
|
220
|
+
steps: [
|
|
221
|
+
{ name: 'Lint', run: 'bun run lint' },
|
|
222
|
+
],
|
|
223
|
+
},
|
|
224
|
+
test: {
|
|
225
|
+
name: 'Test',
|
|
226
|
+
runsOn: 'bun',
|
|
227
|
+
needs: ['install'],
|
|
228
|
+
steps: [
|
|
229
|
+
{ name: 'Test', run: 'bun test --coverage' },
|
|
230
|
+
],
|
|
231
|
+
},
|
|
232
|
+
build: {
|
|
233
|
+
name: 'Build',
|
|
234
|
+
runsOn: 'bun',
|
|
235
|
+
needs: ['lint', 'test'],
|
|
236
|
+
steps: [
|
|
237
|
+
{ name: 'Build', run: 'bun run build' },
|
|
238
|
+
],
|
|
239
|
+
},
|
|
240
|
+
deploy: {
|
|
241
|
+
name: 'Deploy',
|
|
242
|
+
runsOn: 'bun',
|
|
243
|
+
needs: ['build'],
|
|
244
|
+
steps: [
|
|
245
|
+
{ name: 'Deploy', run: 'bun run deploy' },
|
|
246
|
+
],
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
const runner = createRunner();
|
|
252
|
+
const run = await runner.runWorkflow(pipeline);
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## License
|
|
256
|
+
|
|
257
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ebowwa/workflows - CI/CD Workflow System
|
|
3
|
+
*
|
|
4
|
+
* A GitHub Actions-like workflow system with process-level isolation,
|
|
5
|
+
* job scheduling, and real-time event streaming.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { createRunner, WorkflowSchema } from '@ebowwa/workflows';
|
|
10
|
+
*
|
|
11
|
+
* const workflow = WorkflowSchema.parse({
|
|
12
|
+
* id: 'build-test',
|
|
13
|
+
* name: 'Build and Test',
|
|
14
|
+
* triggers: [{ type: 'manual' }],
|
|
15
|
+
* jobs: {
|
|
16
|
+
* build: {
|
|
17
|
+
* name: 'Build',
|
|
18
|
+
* runsOn: 'bun',
|
|
19
|
+
* steps: [
|
|
20
|
+
* { name: 'Install', run: 'bun install' },
|
|
21
|
+
* { name: 'Build', run: 'bun run build' },
|
|
22
|
+
* ],
|
|
23
|
+
* },
|
|
24
|
+
* test: {
|
|
25
|
+
* name: 'Test',
|
|
26
|
+
* runsOn: 'bun',
|
|
27
|
+
* needs: ['build'],
|
|
28
|
+
* steps: [
|
|
29
|
+
* { name: 'Test', run: 'bun test' },
|
|
30
|
+
* ],
|
|
31
|
+
* },
|
|
32
|
+
* },
|
|
33
|
+
* });
|
|
34
|
+
*
|
|
35
|
+
* const runner = createRunner();
|
|
36
|
+
* runner.on('event', (event) => console.log(event));
|
|
37
|
+
* runner.on('log', (log) => process.stdout.write(log.content));
|
|
38
|
+
*
|
|
39
|
+
* const run = await runner.runWorkflow(workflow);
|
|
40
|
+
* console.log(`Workflow ${run.status}`);
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export * from './types.js';
|
|
44
|
+
export { ProcessSandbox, createSandbox, evaluateCondition, type SandboxOptions, type ActiveProcess, } from './sandbox.js';
|
|
45
|
+
export { JobScheduler, buildDependencyGraph, createExecutionPlan, getReadyJobs, type JobNode, type ExecutionPlan, } from './scheduler.js';
|
|
46
|
+
export { WorkflowRunner, createRunner, type RunnerOptions, type RunOptions, } from './runner.js';
|
|
47
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAGH,cAAc,YAAY,CAAC;AAG3B,OAAO,EACL,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,KAAK,cAAc,EACnB,KAAK,aAAa,GACnB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,YAAY,EACZ,oBAAoB,EACpB,mBAAmB,EACnB,YAAY,EACZ,KAAK,OAAO,EACZ,KAAK,aAAa,GACnB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,cAAc,EACd,YAAY,EACZ,KAAK,aAAa,EAClB,KAAK,UAAU,GAChB,MAAM,aAAa,CAAC"}
|