mcpField
C
camunda-forms

camunda-forms

github.com/camunda開発26123 回インストール1 日前に更新
リポジトリ

camunda-forms について

camunda-forms は、Camunda 8.8 以降のユーザータスクや開始イベント向けフォーム JSON スキーマを作成するスキルです。コンポーネント配置、プロセス変数との連携、検証、条件付き表示、スキーマ確認を扱います。

主な機能

  1. 01.form スキーマの作成
  2. 02入力・表示・レイアウトコンポーネントの設定
  3. 03フィールドとプロセス変数の連携
  4. 04検証と条件付き表示の設定
  5. 05公式スキーマによるフォーム検証

活用シーン

  1. 01ユーザータスク用フォームの作成
  2. 02プロセス開始イベント用フォームの作成
  3. 03プロセス変数による入力値の設定と保存
  4. 04デプロイ前のフォームスキーマ確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/camunda/skills --skill camunda-forms

インストール後、Claude Code で/camunda-formsを入力して読み込まれたか確認します。

同梱ファイルportability.jsonreferences/component-reference.md

詳細

Camunda Forms

Camunda 8.8+ のユーザータスクと開始イベント用の Camunda Form JSON スキーマを作成します。

前提条件

  • Camunda 8.8+ クラスター

関連項目

  • camunda-bpmn:<zeebe:formDefinition formId="..."/> を使用してフォームをユーザータスクにリンクする場合に使用します
  • camunda-feel:フォームの検証式と条件付き表示ロジックに使用します

手順

フォームの基本

Camunda Forms は .json ではなく、拡張子が .form の JSON ファイルです。フォームの id フィールドを使って BPMN ユーザータスクにリンクします。このフィールドは、ユーザータスク内の <zeebe:formDefinition formId="..."/> の formId 属性と一致する必要があります。ユーザータスク自体にも <zeebe:userTask/>(Camunda のユーザータスク実装)が含まれている必要があります。古い formKey 属性を使ってリンクしないでください。これは非推奨のジョブワーカー型ユーザータスクで使用されていたもので、Camunda 8.10 で削除されています。BPMN 側については、camunda-bpmn の「Form Definition」を参照してください。

フォームの構造

例 — 最小限のフォームの骨組み:

{
  "components": [],
  "executionPlatform": "Camunda Cloud",
  "executionPlatformVersion": "8.8.0",
  "exporter": { "name": "Camunda Modeler", "version": "5.34.0" },
  "schemaVersion": 18,
  "id": "my-form-id",
  "type": "default"
}

すべてのメタデータフィールドが必須です。schemaVersion: 18 と executionPlatformVersion: "8.8.0" を使用してください。

コンポーネント

各コンポーネントには type、id、layout が必要です。入力コンポーネントには key(プロセス変数名に対応)と label も必要です。

{
  "type": "textfield",
  "id": "Field_Name",
  "key": "customerName",
  "label": "Customer Name",
  "layout": { "row": "row_0", "columns": null }
}

入力コンポーネント:textfield、textarea、number、checkbox、checklist、radio、select、taglist、datetime

表示コンポーネント:text(Markdown)、html、image、separator、button

レイアウトコンポーネント:group、spacer

スキーマのプロパティ名は正確に使用してください。

  • 入力の初期値は defaultValue で設定します。コンポーネントに value を使用しないでください。value は { "label": "High", "value": "high" } のようなオプションオブジェクト内でのみ使用します。
  • 送信コントロールには、action: "submit" を指定した button コンポーネントを使用します。type: "submit" は使用せず、ボタンに key を追加しないでください。
{
  "type": "textfield",
  "id": "Field_Name",
  "key": "customerName",
  "label": "Customer Name",
  "defaultValue": "Ada",
  "layout": { "row": "row_0", "columns": null }
}
{
  "type": "button",
  "id": "Button_submit",
  "label": "Submit",
  "action": "submit",
  "layout": { "row": "row_1", "columns": null }
}

各コンポーネントタイプのプロパティについて詳しくは、references/component-reference.md を参照してください。

レイアウト

コンポーネントは行ごとに配置されます。同じ行にコンポーネントを配置すると、横並びで表示されます。

{ "type": "textfield", "id": "F1", "key": "firstName", "label": "First Name", "layout": { "row": "row_0", "columns": null } },
{ "type": "textfield", "id": "F2", "key": "lastName", "label": "Last Name", "layout": { "row": "row_0", "columns": null } }
変数のバインド

key プロパティは、フォームフィールドをプロセス変数に対応付けます。

  • 読み込み時:変数が存在する場合、その値がフィールドに事前入力されます
  • 送信時:フィールドの値が変数に書き戻されます
検証
{
  "validate": {
    "required": true,
    "minLength": 2,
    "maxLength": 100,
    "min": 0,
    "max": 10000,
    "pattern": "^[A-Z]{2}[0-9]+$",
    "validationExpression": "=amount <= budget"
  }
}

カスタムエラーメッセージには、requiredErrorMessage と patternErrorMessage を使用します。

条件付き表示

FEEL を使用して、他のフィールドの値に基づいてフィールドを非表示または表示します。

{
  "conditional": {
    "hide": "=approved = false"
  }
}

式は、すべてのフォームフィールドの値とプロセス変数を対象に評価されます。

Select/Radio/Checklist のオプション

静的な値:

{
  "type": "select",
  "values": [
    { "label": "Low", "value": "low" },
    { "label": "Medium", "value": "medium" },
    { "label": "High", "value": "high" }
  ]
}

プロセス変数からの動的な値:

{
  "type": "select",
  "valuesExpression": "=departments"
}

変数は {label, value} オブジェクトのリストにしてください。

読み取り専用フィールド

編集を許可せずにデータを表示します。

{
  "type": "textfield",
  "key": "orderId",
  "label": "Order ID",
  "readonly": true
}
テキスト/Markdown

Markdown を使って静的なテキストや手順を表示します。

{
  "type": "text",
  "text": "### Review Details\n\nPlease review the information below.",
  "id": "Text_Header",
  "layout": { "row": "row_0", "columns": null }
}
グループ

関連するフィールドを整理します。

{
  "type": "group",
  "label": "Contact Information",
  "components": [
    { "type": "textfield", "id": "F1", "key": "email", "label": "Email", "layout": { "row": "row_g0", "columns": null } },
    { "type": "textfield", "id": "F2", "key": "phone", "label": "Phone", "layout": { "row": "row_g1", "columns": null } }
  ],
  "id": "Group_Contact",
  "layout": { "row": "row_1", "columns": null }
}
出力形式

完全な .form JSON ファイルを生成します。次の点を確認してください。

  • すべての id 値がフォーム内で一意である
  • key 値が想定されるプロセス変数名と一致している
  • 入力のデフォルト値には defaultValue を使用し、送信コントロールには key を付けず、type: "button" と action: "submit" を指定している
  • layout.row の値が連番(row_0、row_1、...)になっている
  • メタデータフィールドが存在し、正しく設定されている
スキーマ検証ループ(デプロイ前のリント)

.form ファイルを作成または編集した後は、提示またはデプロイする前に、公式の Camunda フォームスキーマに照らして検証してください。ajv と ajv-errors プラグインを直接使用します。公式スキーマではコンポーネントの拡張プロパティが許可されているため、以下のヘルパーでは、既知の無効なコンポーネント形状(value、type: "submit"、ボタンの key)も拒否します。このスキーマでは errorMessage キーワードが使われているため、単純な ajv-cli の実行は失敗します。ajv-cli を使用する場合は、--require で ajv-errors を読み込んでください。すべてのコマンドはプロジェクトルートから実行します。

npm install --save-dev ajv ajv-errors @bpmn-io/[email protected]

# Create the validation helper and commit it as a project tool
cat > validate-form.cjs << 'EOF'
const Ajv = require('ajv');
const addErrors = require('ajv-errors');
const fs = require('fs');
const schema = require('@bpmn-io/form-json-schema/resources/schema.json');
const file = process.argv[2];
if (!file) { console.error('Usage: node validate-form.cjs <path-to-form.form>'); process.exit(1); }
let form;
try { form = JSON.parse(fs.readFileSync(file, 'utf8')); }
catch (e) { console.error(`Cannot read/parse ${file}: ${e.message}`); process.exit(1); }
const ajv = new Ajv({ allErrors: true, strict: false });
addErrors(ajv);
const validate = ajv.compile(schema);
if (!validate(form)) { console.error(JSON.stringify(validate.errors, null, 2)); process.exit(1); }
function invalidComponentShapes(components, path = 'components') {
  if (!Array.isArray(components)) return [];
  const errors = [];
  for (const [index, component] of components.entries()) {
    if (!component || typeof component !== 'object' || Array.isArray(component)) continue;
    const location = `${path}[${index}]`;
    if (Object.prototype.hasOwnProperty.call(component, 'value')) {
      errors.push(`${location}: use defaultValue instead of value on a component`);
    }
    if (component.type === 'submit') {
      errors.push(`${location}: use type "button" with action "submit"`);
    }
    if (component.type === 'button' && Object.prototype.hasOwnProperty.call(component, 'key')) {
      errors.push(`${location}: buttons must not define key`);
    }
    errors.push(...invalidComponentShapes(component.components, `${location}.components`));
  }
  return errors;
}
const shapeErrors = invalidComponentShapes(form.components);
if (shapeErrors.length) { console.error(JSON.stringify(shapeErrors, null, 2)); process.exit(1); }
console.log('Valid ✓');
EOF

node validate-form.cjs path/to/form.form

複数のフォーム(ネストされたディレクトリ内のものを含む)を検証する場合は、すべてのファイルをループ処理し、終了する前にすべての失敗を収集します。

failed=0
# Use find for recursive discovery; replace with *.form for flat directories
while IFS= read -r f; do
  node validate-form.cjs "$f" || { echo "FAILED: $f"; failed=1; }
done < <(find . -name '*.form' -not -path '*/node_modules/*')
exit $failed

よくあるスキーマキーワードと修正方法:

キーワード一般的な意味一般的な修正方法
required必須フィールドがありませんエラーメッセージに記載された不足プロパティを追加します
additionalPropertiesこのオブジェクトに不明なプロパティがありますサポートされていないプロパティを削除します
typeJSON 値の型が誤っています値を期待される型(string/number/boolean/object/array)に変更します
enum / const値が許可されたセットに含まれていません許可された値のいずれかに置き換えます
pattern文字列の形式が無効です(多くの場合、id/key)必須の正規表現(通常は英数字とアンダースコアの形式)に一致するよう名前を変更します

トラブルシューティング

  • フォームが Tasklist に表示されない — BPMN のユーザータスクに <zeebe:userTask/> と、フォームの id フィールドに一致する <zeebe:formDefinition formId="..."/> が含まれていることを確認してください。従来の formKey 属性は Camunda 8.10 で削除されました。
  • schemaVersion の不一致エラー — schemaVersion: 18 と executionPlatformVersion: "8.8.0" を設定してください。古い値は 8.8 以降のクラスターで拒否されます。
  • 条件付きフィールドが常に非表示になる — conditional.hide は、非表示にする場合に true を返す FEEL 式です。= の接頭辞を忘れると、リテラル文字列として扱われます。FEEL の詳細については、camunda-feel § よくあるパターンを参照してください。

参考資料

詳細なリファレンス資料は references/ から参照してください:

  • component-reference.md — 各コンポーネントタイプ(textfield、number、select、datetime など)のプロパティと例を網羅しています

コメント