@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.
@@ -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.36",
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.19",
20
- "@bpmnkit/ascii": "0.0.29",
21
- "@bpmnkit/connector-gen": "0.0.14",
22
- "@bpmnkit/core": "0.1.1",
23
- "@bpmnkit/engine": "0.1.29",
24
- "@bpmnkit/profiles": "0.0.17",
25
- "@bpmnkit/proxy": "0.0.32"
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 AIKit Tool Reference
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
- **Parameters**
133
- | Name | Required | Description |
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
- ### `bpmn_run_history`
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
- **Parameters**
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
- Returns `{ "decisions": [] }` if no business rule tasks with `decisionId` are found.
239
-
240
- ---
241
-
242
- ## Pattern tools
243
-
244
- ### `pattern_list`
245
-
246
- List all available domain process patterns.
247
-
248
- **Parameters** none
249
-
250
- **Returns** `{ patterns: [{ id, name, description, keywords }], total: number }`
251
-
252
- Call this at the start of any skill to check whether a domain pattern applies. Match by comparing keywords against the user's request.
253
-
254
- ---
255
-
256
- ### `pattern_get`
257
-
258
- Get the full content of a domain pattern: readme, worker specs, variations, and a compact BPMN template.
259
-
260
- **Parameters**
261
- | Name | Required | Description |
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: Deploy a BPMN process to local reebe or Camunda 8
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 at the given path.
7
+ Deploy the BPMN process: $ARGUMENTS
8
8
 
9
- ## File to deploy
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
- $ARGUMENTS
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
- 1. Call `mcp__bpmnkit-aikit__bpmn_validate` on the file to check for errors before deploying.
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
- 2. Ask: **"Deploy to local reebe or Camunda 8?"**
28
+ ## Step 3 Verify and summarize
20
29
 
21
- 3. Call `mcp__bpmnkit-aikit__bpmn_deploy` with the chosen target:
22
- - `"local"` deploys to the local reebe instance at ZEEBE_ADDRESS
23
- - `"camunda8"` — deploys using the active casen profile (run `casen profile create` if not set up)
30
+ ```sh
31
+ casen process-definition list --output json
32
+ ```
24
33
 
25
- 4. Report the result:
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
- 5. If any scaffolded workers exist in ./workers/, remind:
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.
@@ -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 end-to-end using BPMNKit AIKit tools. Work through these steps in order.
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 — Check for a domain pattern
15
+ ## Step 1 — Resolve external interactions
16
16
 
17
- Call `mcp__bpmnkit-aikit__pattern_list` to see available domain patterns.
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
- > Using the MCP tool `mcp__bpmnkit-aikit__bpmn_create`, generate a BPMN process for: **$ARGUMENTS**
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 — Implement: Wire workers
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
- ## Step 4 — Review: Validate the BPMN
50
-
51
- Spawn a subagent with this task:
25
+ ```sh
26
+ casen synth <slug>.plan.json --output <slug>.bpmn
27
+ ```
52
28
 
53
- > Call `mcp__bpmnkit-aikit__bpmn_validate` on the BPMN file from Step 2.
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
- ## Step 5 Test: Check coverage
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
- Spawn a subagent with this task:
35
+ ```sh
36
+ casen test <slug>.bpmn
37
+ ```
62
38
 
63
- > Call `mcp__bpmnkit-aikit__bpmn_simulate` on the BPMN file from Step 2 with an empty scenarios array.
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
- Worker coverage: <covered>/<total> service tasks
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 reebe, deploy to Camunda 8, or skip deployment?"**
55
+ Then ask: **"Deploy to local Reebe, deploy to Camunda 8, or skip?"**
90
56
 
91
- - If "local": call `mcp__bpmnkit-aikit__bpmn_deploy` with `target: "local"`
92
- - If "camunda8": call `mcp__bpmnkit-aikit__bpmn_deploy` with `target: "camunda8"`
93
- - If "skip": done
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