@bpmnkit/cli 0.0.36 → 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 +3 -1
- package/dist/commands/connector.js +82 -0
- package/dist/commands/deploy.js +70 -0
- package/dist/commands/generate.js +79 -16
- package/dist/commands/index.js +8 -0
- package/dist/commands/lint.js +36 -6
- package/dist/commands/pattern.js +55 -0
- package/dist/commands/plan.js +70 -0
- package/dist/commands/skills.js +6 -2
- package/dist/commands/synth.js +103 -0
- package/package.json +10 -8
- package/skills/aikit.md +34 -255
- package/skills/deploy.md +23 -20
- package/skills/implement.md +25 -59
- package/skills/review.md +25 -19
- package/skills/test.md +20 -22
- package/skills/design.md +0 -87
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { applyConnectorTemplate } from "@bpmnkit/connectors";
|
|
4
|
+
import { Bpmn, compilePlan, mergePlan, slugify, uniqueId } from "@bpmnkit/core";
|
|
5
|
+
async function readPlan(path) {
|
|
6
|
+
const text = await readFile(resolve(path), "utf-8");
|
|
7
|
+
return JSON.parse(text);
|
|
8
|
+
}
|
|
9
|
+
/** Convert plan-embedded test scenarios to the `.bpmn.tests.json` shape consumed by `casen test`. */
|
|
10
|
+
export function toScenarioSidecar(tests) {
|
|
11
|
+
const taken = new Set();
|
|
12
|
+
return tests.map((t) => {
|
|
13
|
+
const id = uniqueId(slugify(t.name), taken);
|
|
14
|
+
const mocks = Object.fromEntries(Object.entries(t.mocks ?? {}).map(([jobType, mock]) => [
|
|
15
|
+
jobType,
|
|
16
|
+
"error" in mock
|
|
17
|
+
? {
|
|
18
|
+
error: mock.error.message
|
|
19
|
+
? `${mock.error.code}: ${mock.error.message}`
|
|
20
|
+
: mock.error.code,
|
|
21
|
+
}
|
|
22
|
+
: { outputs: mock.outputs },
|
|
23
|
+
]));
|
|
24
|
+
return { id, name: t.name, inputs: t.inputs, mocks, expect: t.expect };
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
const synthCmd = {
|
|
28
|
+
name: "synth",
|
|
29
|
+
description: "Compile a ProcessPlan JSON file into deployable, laid-out BPMN XML",
|
|
30
|
+
args: [{ name: "plan", description: "Path to the ProcessPlan JSON file", required: true }],
|
|
31
|
+
flags: [
|
|
32
|
+
{
|
|
33
|
+
name: "output",
|
|
34
|
+
short: "o",
|
|
35
|
+
description: "Output .bpmn file path (default: <plan>.bpmn)",
|
|
36
|
+
type: "string",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: "merge",
|
|
40
|
+
description: "Merge into an existing .bpmn file instead of creating a new one",
|
|
41
|
+
type: "string",
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: "json",
|
|
45
|
+
description: "Print the result (problems + xml) as JSON instead of writing a file",
|
|
46
|
+
type: "boolean",
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
examples: [
|
|
50
|
+
{ description: "Compile a plan to BPMN", command: "casen synth order-process.plan.json" },
|
|
51
|
+
{
|
|
52
|
+
description: "Extend an existing process",
|
|
53
|
+
command: "casen synth delta.plan.json --merge order-process.bpmn",
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
async run(ctx) {
|
|
57
|
+
const planPath = ctx.positional[0];
|
|
58
|
+
if (!planPath)
|
|
59
|
+
throw new Error("Missing required argument: <plan>");
|
|
60
|
+
const plan = await readPlan(planPath);
|
|
61
|
+
const mergeTarget = typeof ctx.flags.merge === "string" ? ctx.flags.merge : undefined;
|
|
62
|
+
const result = mergeTarget
|
|
63
|
+
? mergePlan(Bpmn.parse(await readFile(resolve(mergeTarget), "utf-8")), plan, {
|
|
64
|
+
resolveConnector: applyConnectorTemplate,
|
|
65
|
+
})
|
|
66
|
+
: compilePlan(plan, { resolveConnector: applyConnectorTemplate });
|
|
67
|
+
if (ctx.flags.json) {
|
|
68
|
+
ctx.output.print(result);
|
|
69
|
+
if (!result.xml)
|
|
70
|
+
process.exitCode = 1;
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (result.problems.length > 0) {
|
|
74
|
+
for (const p of result.problems)
|
|
75
|
+
ctx.output.info(`✖ [${p.path}] ${p.message}`);
|
|
76
|
+
}
|
|
77
|
+
if (!result.xml) {
|
|
78
|
+
throw new Error(`Compilation failed with ${result.problems.length} problem(s) — see above`);
|
|
79
|
+
}
|
|
80
|
+
const outputPath = resolve(typeof ctx.flags.output === "string"
|
|
81
|
+
? ctx.flags.output
|
|
82
|
+
: (mergeTarget ?? planPath.replace(/\.json$/, ".bpmn")));
|
|
83
|
+
await writeFile(outputPath, result.xml, "utf-8");
|
|
84
|
+
if (plan.tests && plan.tests.length > 0) {
|
|
85
|
+
const sidecarPath = `${outputPath}.tests.json`;
|
|
86
|
+
await writeFile(sidecarPath, JSON.stringify(toScenarioSidecar(plan.tests), null, 2), "utf-8");
|
|
87
|
+
ctx.output.info(`Wrote ${sidecarPath} (${plan.tests.length} scenario(s) — run: casen test ${outputPath})`);
|
|
88
|
+
}
|
|
89
|
+
if (result.problems.length > 0) {
|
|
90
|
+
ctx.output.info(`\nWrote ${outputPath} with ${result.problems.length} problem(s) above.`);
|
|
91
|
+
process.exitCode = 1;
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
ctx.output.ok(`Wrote ${outputPath}`);
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
export const synthGroup = {
|
|
99
|
+
name: "synth",
|
|
100
|
+
description: "Compile a ProcessPlan into deployable BPMN — the deterministic AI-generation pipeline",
|
|
101
|
+
commands: [synthCmd],
|
|
102
|
+
};
|
|
103
|
+
//# sourceMappingURL=synth.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bpmnkit/cli",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "Command-line interface for Camunda 8 — deploy, manage, and monitor processes from the terminal",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -16,13 +16,15 @@
|
|
|
16
16
|
"node": ">=20"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@bpmnkit/api": "0.0.
|
|
20
|
-
"@bpmnkit/ascii": "0.0.
|
|
21
|
-
"@bpmnkit/connector-gen": "0.0.
|
|
22
|
-
"@bpmnkit/
|
|
23
|
-
"@bpmnkit/
|
|
24
|
-
"@bpmnkit/
|
|
25
|
-
"@bpmnkit/
|
|
19
|
+
"@bpmnkit/api": "0.0.20",
|
|
20
|
+
"@bpmnkit/ascii": "0.0.31",
|
|
21
|
+
"@bpmnkit/connector-gen": "0.0.15",
|
|
22
|
+
"@bpmnkit/connectors": "0.0.3",
|
|
23
|
+
"@bpmnkit/core": "0.2.0",
|
|
24
|
+
"@bpmnkit/engine": "0.1.31",
|
|
25
|
+
"@bpmnkit/patterns": "0.0.5",
|
|
26
|
+
"@bpmnkit/profiles": "0.0.18",
|
|
27
|
+
"@bpmnkit/proxy": "0.1.0"
|
|
26
28
|
},
|
|
27
29
|
"publishConfig": {
|
|
28
30
|
"access": "public"
|
package/skills/aikit.md
CHANGED
|
@@ -1,267 +1,46 @@
|
|
|
1
|
-
# BPMNKit
|
|
1
|
+
# BPMNKit — Reference
|
|
2
2
|
|
|
3
|
-
This file is installed to `.claude/aikit.md` by `casen skills install`.
|
|
4
|
-
The skill files (`/design`, `/implement`, etc.) reference it with `@.claude/aikit.md`.
|
|
3
|
+
This file is installed to `.claude/aikit.md` by `casen skills install`. The skill files (`/implement`, `/review`, `/test`, `/deploy`) reference it with `@.claude/aikit.md`.
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
## MCP server
|
|
9
|
-
|
|
10
|
-
All tools are exposed by the `bpmnkit-aikit` MCP server configured in `.claude/mcp.json`.
|
|
11
|
-
Tool names follow the pattern `mcp__bpmnkit-aikit__<tool_name>`.
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
## BPMN tools
|
|
16
|
-
|
|
17
|
-
### `bpmn_create`
|
|
18
|
-
|
|
19
|
-
Generate a new BPMN process from a natural language description.
|
|
20
|
-
|
|
21
|
-
- Automatically loads a matching domain pattern for context before calling the AI.
|
|
22
|
-
- Writes the `.bpmn` file to disk.
|
|
23
|
-
|
|
24
|
-
**Parameters**
|
|
25
|
-
| Name | Required | Description |
|
|
26
|
-
|---|---|---|
|
|
27
|
-
| `description` | yes | Natural language description of the process. Include actors, decision points, and expected outcomes. The richer the description, the better the diagram. |
|
|
28
|
-
| `outputDir` | no | Directory to write the file (default: current working directory). |
|
|
29
|
-
|
|
30
|
-
**Returns** `{ path: string, patternMatched: string | null }`
|
|
31
|
-
|
|
32
|
-
**Good description example:**
|
|
33
|
-
> "Invoice approval process with a clerk review step, automatic approval under €500, manager approval for higher amounts, and email notification on rejection."
|
|
34
|
-
|
|
35
|
-
---
|
|
36
|
-
|
|
37
|
-
### `bpmn_read`
|
|
38
|
-
|
|
39
|
-
Read a BPMN file and return its compact JSON representation.
|
|
40
|
-
|
|
41
|
-
**Parameters**
|
|
42
|
-
| Name | Required | Description |
|
|
43
|
-
|---|---|---|
|
|
44
|
-
| `path` | yes | Path to the `.bpmn` file. |
|
|
45
|
-
|
|
46
|
-
**Returns** Compact JSON with shape:
|
|
47
|
-
```json
|
|
48
|
-
{
|
|
49
|
-
"id": "process-id",
|
|
50
|
-
"processes": [{
|
|
51
|
-
"id": "...", "name": "...",
|
|
52
|
-
"elements": [
|
|
53
|
-
{ "type": "startEvent", "id": "...", "name": "..." },
|
|
54
|
-
{ "type": "serviceTask", "id": "...", "name": "...", "jobType": "com.example:do-thing:1" },
|
|
55
|
-
{ "type": "userTask", "id": "...", "name": "...", "formId": "approve-form" },
|
|
56
|
-
{ "type": "businessRuleTask", "id": "...", "name": "...", "decisionId": "credit-check" },
|
|
57
|
-
{ "type": "exclusiveGateway", "id": "...", "name": "..." },
|
|
58
|
-
{ "type": "endEvent", "id": "...", "name": "..." }
|
|
59
|
-
]
|
|
60
|
-
}]
|
|
61
|
-
}
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
Use `jobType` to identify service tasks for worker scaffolding. Use `formId` / `decisionId` to know which tasks need forms/DMN tables.
|
|
65
|
-
|
|
66
|
-
---
|
|
67
|
-
|
|
68
|
-
### `bpmn_update`
|
|
69
|
-
|
|
70
|
-
Update an existing BPMN by describing the change in natural language.
|
|
71
|
-
|
|
72
|
-
**Parameters**
|
|
73
|
-
| Name | Required | Description |
|
|
74
|
-
|---|---|---|
|
|
75
|
-
| `path` | yes | Path to the `.bpmn` file. |
|
|
76
|
-
| `instruction` | yes | What to change, e.g. "Add an error boundary event on the payment task that routes to a manual review lane." |
|
|
77
|
-
|
|
78
|
-
**Returns** `{ path: string, updated: true }`
|
|
79
|
-
|
|
80
|
-
---
|
|
81
|
-
|
|
82
|
-
### `bpmn_validate`
|
|
83
|
-
|
|
84
|
-
Validate a BPMN file using the BPMNKit pattern advisor.
|
|
85
|
-
|
|
86
|
-
**Parameters**
|
|
87
|
-
| Name | Required | Description |
|
|
88
|
-
|---|---|---|
|
|
89
|
-
| `path` | yes | Path to the `.bpmn` file. |
|
|
90
|
-
|
|
91
|
-
**Returns**
|
|
92
|
-
```json
|
|
93
|
-
{
|
|
94
|
-
"summary": { "total": 3, "errors": 1, "warnings": 1, "info": 1, "autoFixable": 2 },
|
|
95
|
-
"findings": [
|
|
96
|
-
{
|
|
97
|
-
"severity": "error" | "warning" | "info",
|
|
98
|
-
"category": "string",
|
|
99
|
-
"message": "string",
|
|
100
|
-
"suggestion": "string",
|
|
101
|
-
"elementIds": ["..."],
|
|
102
|
-
"autoFixable": true
|
|
103
|
-
}
|
|
104
|
-
]
|
|
105
|
-
}
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
Errors block deployment. Warnings and info are advisory.
|
|
109
|
-
|
|
110
|
-
---
|
|
111
|
-
|
|
112
|
-
### `bpmn_deploy`
|
|
113
|
-
|
|
114
|
-
Deploy a BPMN process to a running engine.
|
|
115
|
-
|
|
116
|
-
**Parameters**
|
|
117
|
-
| Name | Required | Description |
|
|
118
|
-
|---|---|---|
|
|
119
|
-
| `path` | yes | Path to the `.bpmn` file. |
|
|
120
|
-
| `target` | yes | `"local"` — local reebe instance (uses `ZEEBE_ADDRESS`). `"camunda8"` — active Camunda 8 profile (set with `casen profile create`). |
|
|
121
|
-
|
|
122
|
-
**Returns** `{ success: true, target: string, result: object }`
|
|
123
|
-
|
|
124
|
-
---
|
|
125
|
-
|
|
126
|
-
### `bpmn_simulate`
|
|
127
|
-
|
|
128
|
-
Structural analysis: validation findings + worker coverage check.
|
|
129
|
-
|
|
130
|
-
> **Note:** Phase 1 only — structural analysis. Full process execution simulation is planned for a future phase.
|
|
5
|
+
These are lightweight, CLI-only slash commands. For the full skill set — `/bpmnkit:implement`, `/bpmnkit:extend`, `/bpmnkit:agent`, `/bpmnkit:connect`, plus generated reference docs (`plan-format.md`, `connectors.md`, `agentic.md`, `feel.md`) — install the Claude Code plugin instead:
|
|
131
6
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
| `path` | yes | Path to the `.bpmn` file. |
|
|
136
|
-
|
|
137
|
-
**Returns**
|
|
138
|
-
```json
|
|
139
|
-
{
|
|
140
|
-
"validation": { "errors": 0, "findings": [] },
|
|
141
|
-
"workerCoverage": {
|
|
142
|
-
"total": 3,
|
|
143
|
-
"covered": 2,
|
|
144
|
-
"missing": ["com.example:send-invoice:1"]
|
|
145
|
-
}
|
|
146
|
-
}
|
|
7
|
+
```sh
|
|
8
|
+
/plugin marketplace add github:bpmnkit/monorepo
|
|
9
|
+
/plugin install bpmnkit
|
|
147
10
|
```
|
|
148
11
|
|
|
149
12
|
---
|
|
150
13
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
Query recent process executions from the local proxy.
|
|
154
|
-
|
|
155
|
-
**Parameters**
|
|
156
|
-
| Name | Required | Description |
|
|
157
|
-
|---|---|---|
|
|
158
|
-
| `processId` | no | Filter by process definition ID. |
|
|
159
|
-
|
|
160
|
-
**Returns** `{ runs: [...] }` — up to 20 recent executions.
|
|
161
|
-
|
|
162
|
-
---
|
|
163
|
-
|
|
164
|
-
## Worker tools
|
|
165
|
-
|
|
166
|
-
### `worker_list`
|
|
167
|
-
|
|
168
|
-
List all available workers: built-in BPMNKit workers and any scaffolded workers found in `./workers/`.
|
|
169
|
-
|
|
170
|
-
**Parameters** none
|
|
171
|
-
|
|
172
|
-
**Returns** `{ workers: [{ jobType, name, description, ... }], total: number }`
|
|
173
|
-
|
|
174
|
-
---
|
|
175
|
-
|
|
176
|
-
### `worker_scaffold`
|
|
177
|
-
|
|
178
|
-
Scaffold a TypeScript worker for a Zeebe job type. Generates `index.ts`, `package.json`, `tsconfig.json`, `README.md` in `./workers/<slug>/`.
|
|
179
|
-
|
|
180
|
-
**Parameters**
|
|
181
|
-
| Name | Required | Description |
|
|
182
|
-
|---|---|---|
|
|
183
|
-
| `jobType` | yes | Zeebe job type string, e.g. `com.example:send-invoice:1`. |
|
|
184
|
-
| `description` | no | What this worker does. |
|
|
185
|
-
| `inputs` | no | Object mapping input variable names to type descriptions, e.g. `{ "invoiceId": "string", "amount": "number" }`. |
|
|
186
|
-
| `outputs` | no | Object mapping output variable names to type descriptions. |
|
|
187
|
-
|
|
188
|
-
**Returns** `{ path: string, files: [...], jobType: string, note: string }`
|
|
189
|
-
|
|
190
|
-
After scaffolding: `cd workers/<slug> && npm install && npm start`. Edit `index.ts` to implement `handle()`.
|
|
191
|
-
|
|
192
|
-
---
|
|
193
|
-
|
|
194
|
-
## Form & DMN tools
|
|
195
|
-
|
|
196
|
-
### `form_create`
|
|
197
|
-
|
|
198
|
-
Generate Camunda form JSON for all `userTask` elements in a BPMN that have a `formId`. Writes one `.form` file per task.
|
|
14
|
+
## The pipeline
|
|
199
15
|
|
|
200
|
-
|
|
201
|
-
| Name | Required | Description |
|
|
202
|
-
|---|---|---|
|
|
203
|
-
| `bpmnPath` | yes | Path to the `.bpmn` file. |
|
|
204
|
-
| `outputDir` | no | Where to write form files (default: same directory as the BPMN). |
|
|
16
|
+
Every process is authored as a `ProcessPlan` JSON file, never hand-written BPMN XML:
|
|
205
17
|
|
|
206
|
-
**Returns**
|
|
207
|
-
```json
|
|
208
|
-
{
|
|
209
|
-
"forms": [
|
|
210
|
-
{ "taskId": "...", "taskName": "...", "formId": "...", "path": "path/to/form-id.form" }
|
|
211
|
-
]
|
|
212
|
-
}
|
|
213
18
|
```
|
|
214
|
-
|
|
215
|
-
Returns `{ "forms": [] }` if no user tasks with `formId` are found.
|
|
216
|
-
|
|
217
|
-
---
|
|
218
|
-
|
|
219
|
-
### `dmn_create`
|
|
220
|
-
|
|
221
|
-
Generate DMN decision table XML for all `businessRuleTask` elements in a BPMN that have a `decisionId`. Writes one `.dmn` file per task.
|
|
222
|
-
|
|
223
|
-
**Parameters**
|
|
224
|
-
| Name | Required | Description |
|
|
225
|
-
|---|---|---|
|
|
226
|
-
| `bpmnPath` | yes | Path to the `.bpmn` file. |
|
|
227
|
-
| `outputDir` | no | Where to write DMN files (default: same directory as the BPMN). |
|
|
228
|
-
|
|
229
|
-
**Returns**
|
|
230
|
-
```json
|
|
231
|
-
{
|
|
232
|
-
"decisions": [
|
|
233
|
-
{ "taskId": "...", "taskName": "...", "decisionId": "...", "path": "path/to/decision-id.dmn" }
|
|
234
|
-
]
|
|
235
|
-
}
|
|
19
|
+
<name>.plan.json → casen synth → <name>.bpmn (+ <name>.bpmn.tests.json if plan.tests is set)
|
|
236
20
|
```
|
|
237
21
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
| `domain` | yes | Pattern id (e.g. `"invoice-approval"`) or free-text query (e.g. `"employee onboarding"`). |
|
|
264
|
-
|
|
265
|
-
**Returns** `{ id, name, description, keywords, readme, workers, variations, template }`
|
|
266
|
-
|
|
267
|
-
Pass `pattern.readme` and `pattern.workers` as additional context in the `description` parameter of `bpmn_create`.
|
|
22
|
+
`casen plan schema` prints the full `ProcessPlan` format reference. `casen plan extract <file>.bpmn` lifts an existing process back into plan form (for `/extend`-style changes).
|
|
23
|
+
|
|
24
|
+
## Key commands
|
|
25
|
+
|
|
26
|
+
| Command | Does |
|
|
27
|
+
|---|---|
|
|
28
|
+
| `casen plan schema` | Print the `ProcessPlan` JSON format reference |
|
|
29
|
+
| `casen plan extract <file>.bpmn` | Lift an existing process into `<file>.plan.json` |
|
|
30
|
+
| `casen synth <plan>.json --output <file>.bpmn` | Compile a plan to laid-out, deployable BPMN |
|
|
31
|
+
| `casen synth <plan>.json --merge <file>.bpmn --output <file>.bpmn` | Compile a delta plan and merge it into an existing process |
|
|
32
|
+
| `casen connector search "<query>"` | Find a Camunda connector template by name/keyword |
|
|
33
|
+
| `casen connector show <template-id>` | Required/optional input keys, task type, direction |
|
|
34
|
+
| `casen lint lint <file>.bpmn` | Full static analysis (all categories) |
|
|
35
|
+
| `casen lint lint <file>.bpmn --profile deploy` | Deploy-readiness gate — errors only |
|
|
36
|
+
| `casen lint lint <file>.bpmn --fix` | Apply auto-fixable findings, write back |
|
|
37
|
+
| `casen test <file>.bpmn` | Run scenarios from `<file>.bpmn.tests.json` |
|
|
38
|
+
| `casen deploy deploy <file>.bpmn [--target camunda8]` | Deploy to local Reebe (default) or Camunda 8 |
|
|
39
|
+
| `casen worker start` | Start every scaffolded worker in `./workers/` |
|
|
40
|
+
|
|
41
|
+
## Conventions
|
|
42
|
+
|
|
43
|
+
- A value starting with `=` is a FEEL expression; without it, it's a literal string.
|
|
44
|
+
- Secrets always use the `{{secrets.NAME}}` placeholder — never a literal credential.
|
|
45
|
+
- Every plan step's `id`/`name` should follow Camunda naming conventions ("Verb Object" tasks, "Object + past participle" start events, "?" gateway questions) — see the full plugin's `references/modeling-style.md` for the complete list.
|
|
46
|
+
- Worker stubs use `@bpmnkit/worker-client`'s `createWorkerClient({ workerName }).poll(jobType)` API, written to `workers/<slug>/index.ts`.
|
package/skills/deploy.md
CHANGED
|
@@ -1,33 +1,36 @@
|
|
|
1
1
|
---
|
|
2
|
-
description:
|
|
2
|
+
description: Gate a BPMN process on deploy-readiness, then deploy it to local Reebe or Camunda 8.
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
@.claude/aikit.md
|
|
6
6
|
|
|
7
|
-
Deploy the BPMN process
|
|
7
|
+
Deploy the BPMN process: $ARGUMENTS
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Extract the `.bpmn` filename (find the single `.bpmn` in cwd, or ask, if not given) and destination (`--local` default, or `--camunda`).
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
## Step 1 — Gate on deploy-readiness
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
```sh
|
|
14
|
+
casen lint lint <file>.bpmn --profile deploy
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
If this reports any errors, stop and fix them first (or run `/review`) — do not deploy with deploy-profile errors.
|
|
18
|
+
|
|
19
|
+
## Step 2 — Deploy
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
casen deploy deploy <file>.bpmn # local Reebe
|
|
23
|
+
casen deploy deploy <file>.bpmn --target camunda8 # active Camunda 8 profile
|
|
24
|
+
```
|
|
14
25
|
|
|
15
|
-
|
|
16
|
-
- If there are errors, show them and ask: **"Fix errors first or deploy anyway?"**
|
|
17
|
-
- If warnings only: show them but proceed.
|
|
26
|
+
Local deploy unreachable → tell the user to run `casen reebe start --port 26500` first, then retry. Camunda 8 deploy with no active profile → tell the user to run `casen profile create <name> --base-url <url> --auth-type bearer --token <token>` then `casen profile use <name>`, then retry.
|
|
18
27
|
|
|
19
|
-
|
|
28
|
+
## Step 3 — Verify and summarize
|
|
20
29
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
30
|
+
```sh
|
|
31
|
+
casen process-definition list --output json
|
|
32
|
+
```
|
|
24
33
|
|
|
25
|
-
|
|
26
|
-
- On success: "Deployed successfully. Process ID: <id>"
|
|
27
|
-
- On failure: show the error and suggest a fix (profile not set up, reebe not running, etc.)
|
|
34
|
+
Report: `Deployed: <process-id> version: <N> target: <local|camunda8>`.
|
|
28
35
|
|
|
29
|
-
|
|
30
|
-
```
|
|
31
|
-
Don't forget to start your workers:
|
|
32
|
-
casen worker start
|
|
33
|
-
```
|
|
36
|
+
If any scaffolded workers exist in `./workers/`, remind: `casen worker start`. Remind about any `{{secrets.NAME}}` the process references — they must be provisioned in the target engine's secret store.
|
package/skills/implement.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Implement a BPMN process end-to-end from a natural language description
|
|
2
|
+
description: Implement a BPMN process end-to-end from a natural language description — plan, compile, test, deploy.
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
@.claude/aikit.md
|
|
6
6
|
|
|
7
|
-
You are implementing a BPMN process
|
|
7
|
+
You are implementing a BPMN process using `casen`. You never write BPMN XML by hand — every process is authored as a `ProcessPlan` JSON file and compiled with `casen synth`.
|
|
8
8
|
|
|
9
9
|
## Request
|
|
10
10
|
|
|
@@ -12,82 +12,48 @@ $ARGUMENTS
|
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
15
|
-
## Step 1 —
|
|
15
|
+
## Step 1 — Resolve external interactions
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
If any pattern keywords match the request, call `mcp__bpmnkit-aikit__pattern_get` to load the full pattern as context for the next step.
|
|
17
|
+
For each external system the process touches (Slack, email, HTTP, etc.): `casen connector search "<system>"` then `casen connector show <template-id>` for its required inputs. No match → use a plain `jobType` step (a worker gets scaffolded in Step 5).
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
## Step 2 — Plan: Create the BPMN
|
|
23
|
-
|
|
24
|
-
Spawn a subagent with this task:
|
|
19
|
+
## Step 2 — Write the plan
|
|
25
20
|
|
|
26
|
-
|
|
27
|
-
>
|
|
28
|
-
> If a domain pattern was loaded in Step 1, pass its readme and worker specs as additional context in the description parameter.
|
|
29
|
-
>
|
|
30
|
-
> Return the file path of the generated BPMN.
|
|
31
|
-
|
|
32
|
-
---
|
|
21
|
+
Write `<slug>.plan.json` per `casen plan schema`. Name elements clearly (see `.claude/aikit.md`'s naming conventions).
|
|
33
22
|
|
|
34
|
-
## Step 3 —
|
|
35
|
-
|
|
36
|
-
Spawn a subagent with this task:
|
|
37
|
-
|
|
38
|
-
> You are implementing workers for a BPMN process.
|
|
39
|
-
>
|
|
40
|
-
> 1. Call `mcp__bpmnkit-aikit__worker_list` to get the catalog of available workers.
|
|
41
|
-
> 2. Call `mcp__bpmnkit-aikit__bpmn_read` on the BPMN file from Step 2 to find all service task job types.
|
|
42
|
-
> 3. For each service task job type:
|
|
43
|
-
> - If a built-in or previously scaffolded worker matches: note it as "reused"
|
|
44
|
-
> - If no match exists: call `mcp__bpmnkit-aikit__worker_scaffold` with the job type, a description, and expected inputs/outputs derived from the BPMN context
|
|
45
|
-
> 4. Return: a list of `{ jobType, status: "reused" | "scaffolded", workerPath? }` for each service task
|
|
46
|
-
|
|
47
|
-
---
|
|
23
|
+
## Step 3 — Compile
|
|
48
24
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
25
|
+
```sh
|
|
26
|
+
casen synth <slug>.plan.json --output <slug>.bpmn
|
|
27
|
+
```
|
|
52
28
|
|
|
53
|
-
|
|
54
|
-
> Identify any errors that block deployment and any warnings worth noting.
|
|
55
|
-
> Return: `{ errors: [...], warnings: [...] }`
|
|
29
|
+
Fix any reported problems in the plan (never the XML) and re-run — bounded to 2 retries before asking the user.
|
|
56
30
|
|
|
57
|
-
|
|
31
|
+
## Step 4 — Test
|
|
58
32
|
|
|
59
|
-
|
|
33
|
+
Add a `tests` array to the plan covering the happy path and every branch/boundary, re-synth (writes `<slug>.bpmn.tests.json`), then:
|
|
60
34
|
|
|
61
|
-
|
|
35
|
+
```sh
|
|
36
|
+
casen test <slug>.bpmn
|
|
37
|
+
```
|
|
62
38
|
|
|
63
|
-
|
|
64
|
-
> Return: worker coverage report (total service tasks, covered, missing)
|
|
39
|
+
## Step 5 — Scaffold workers
|
|
65
40
|
|
|
66
|
-
|
|
41
|
+
For every job-type step with no existing worker, write `workers/<slug>/index.ts` using `@bpmnkit/worker-client`'s `createWorkerClient({ workerName }).poll(jobType)` API.
|
|
67
42
|
|
|
68
43
|
## Step 6 — Present summary and ask to deploy
|
|
69
44
|
|
|
70
|
-
Collect all results and present a summary:
|
|
71
|
-
|
|
72
45
|
```
|
|
73
46
|
BPMN file: <path>
|
|
74
|
-
Pattern used: <id or "none">
|
|
75
|
-
|
|
76
|
-
Workers:
|
|
77
|
-
✓ reused: <list>
|
|
78
|
-
+ scaffolded: <list with paths>
|
|
79
|
-
|
|
80
|
-
Validation:
|
|
81
|
-
Errors: <count> — <list if any>
|
|
82
|
-
Warnings: <count> — <list if any>
|
|
83
47
|
|
|
84
|
-
|
|
48
|
+
Connectors used: <list, with required secrets — never their values>
|
|
49
|
+
Workers: reused <list> / scaffolded <list with paths>
|
|
50
|
+
Tests: X/Y passed
|
|
85
51
|
|
|
86
52
|
Scaffolded workers require: npm install && npm start (in each workers/<name>/ directory)
|
|
87
53
|
```
|
|
88
54
|
|
|
89
|
-
Then ask: **"Deploy to local
|
|
55
|
+
Then ask: **"Deploy to local Reebe, deploy to Camunda 8, or skip?"**
|
|
90
56
|
|
|
91
|
-
-
|
|
92
|
-
-
|
|
93
|
-
-
|
|
57
|
+
- local: `casen lint lint <slug>.bpmn --profile deploy` (must be zero errors) then `casen deploy deploy <slug>.bpmn`
|
|
58
|
+
- camunda8: same lint gate, then `casen deploy deploy <slug>.bpmn --target camunda8`
|
|
59
|
+
- skip: done
|