Formly Agent Contracts
Formly Contract
Formly Contract は、Angular Formly のフィールド設定を、E2E テスト作成者やコーディングエージェントがフォームの構造を推測することなく理解できる、安定したバージョン管理された JSON に変換します。
FormlyFieldConfig[] が与えられると、アダプターは以下を記述します:
フォーム内のコントロール、表示コンテンツ、グループ、繰り返し可能なテンプレート
各フィールドのモデルパス、Formly タイプ、ラベル、制約、選択肢
既知の可視性、必須、読み取り専用、無効、動的オプションの動作
data-testid、data-test-id、data-cyなどの正確な、またはアプリケーション由来のテストロケーター設定から直接得られたもの、制御された Formly ビルドで解決されたもの、まだ不明なもの
安全に表現できない動作に対する安定した診断
結果は、厳密なランタイム検証、正規のシリアライゼーション、コンテンツハッシュを備えた決定論的な Form Contract です。このコントラクトは、Cypress/Playwright のテスト計画や将来のエージェントツールのための信頼できる入力となることを意図しています。Formly のライブランタイムオブジェクトのダンプではありません。
What exists today
このリポジトリは現在、スキーマ v0.3 と 2 つのワークスペースパッケージを提供しています:
Package | Purpose |
| コントラクト DTO、ランタイム検証、正規 JSON、SHA-256 コンテンツハッシュ |
| Formly 6.1 向けの安全な宣言的抽出と信頼できるシナリオコンパイル |
また、以下も含まれます:
合成ゴールデンフォームを使用した決定論的 CLI デモ
12 の合成 Formly フィクスチャを備えたブラウザレンダリング Angular テストアプリケーション
固定された Angular
20.3.29と Formly6.1.8の組み合わせに対する互換性カバレッジ
パーサーとコントラクトが現在の製品です。本番 MCP サーバー、自動 Playwright 生成、ブラウザ観測、アプリケーションソースの検出は将来のレイヤーであり、この MVP には含まれていません。
Related MCP server: SpecBridge MCP
Use it in your own Angular/Formly codebase
このパッケージは、Angular アプリケーションの横でビルド/テストツールとして実行されます。アプリケーションのブラウザバンドルに追加する必要はありません。典型的な導入フローは次のとおりです:
application-owned Formly factories
|
generation script or CI job
|
versioned contract JSON
|
Playwright / Cypress / agent tooling1. Add the packages
パッケージはまだ npm に公開されていません。最初のリリースまで、このリポジトリを利用側アプリケーションの隣にクローンし、2 つのパッケージをビルドしてください:
git clone https://github.com/dills122/formly-contract.git
cd formly-contract
pnpm install --frozen-lockfile
pnpm --filter @formly-contract/contract-schema build
pnpm --filter @formly-contract/formly-adapter build次に、利用側アプリケーションの package.json からリンクします(チェックアウトに合わせて相対パスを調整してください):
{
"devDependencies": {
"@formly-contract/contract-schema": "link:../formly-contract/packages/contract-schema",
"@formly-contract/formly-adapter": "link:../formly-contract/packages/formly-adapter"
}
}利用側アプリケーションで pnpm install を実行します。アプリケーションは互換性のある Angular と Formly のピア依存関係をすでに提供している必要があります。現在テストされている組み合わせは、Angular 20.3.29 と Formly 6.1.8 です。パッケージが公開されると、通常のバージョン付き pnpm add --save-dev 依存関係がこれらのローカルリンクに取って代わります。
2. Select the forms to expose
アプリケーションソースの検出は意図的に自動化されていません。コントラクトジェネレーターに検査させたいフォームファクトリーのみをインポートする、アプリケーション所有の小さなレジストリを作成してください:
// tools/contract-forms.ts
import type { FormlyFieldConfig } from '@ngx-formly/core';
import { createClaimFields } from '../src/app/claims/claim.fields';
import { createCustomerFields } from '../src/app/customers/customer.fields';
export interface ContractFormTarget {
id: string;
createFields: () => FormlyFieldConfig[];
}
export const contractForms: ContractFormTarget[] = [
{ id: 'claims.create', createFields: () => createClaimFields() },
{ id: 'customers.edit', createFields: () => createCustomerFields() },
];各ファクトリーは新しいフィールドツリーを返す必要があります。ファクトリーがアプリケーション入力を必要とする場合は、ローカル開発と CI で安全に使用できる合成値を持つクロージャーでラップしてください。
3. Generate contract artifacts
アプリケーションリポジトリにビルド時スクリプトを追加します:
// tools/generate-form-contracts.ts
import { mkdir, writeFile } from 'node:fs/promises';
import { resolve } from 'node:path';
import { canonicalStringify } from '@formly-contract/contract-schema';
import { extractFormContract } from '@formly-contract/formly-adapter';
import { contractForms } from './contract-forms';
const outputDirectory = resolve('artifacts/form-contracts');
await mkdir(outputDirectory, { recursive: true });
for (const target of contractForms) {
const { contract, diagnostics } = extractFormContract({
formId: target.id,
fields: target.createFields(),
});
await writeFile(
resolve(outputDirectory, `${target.id}.json`),
`${canonicalStringify(contract)}\n`,
);
console.log(
`${target.id}: ${contract.nodes.length} root nodes, ${diagnostics.length} diagnostics`,
);
}このファイルを、利用側リポジトリで既に使用されている TypeScript ランナーで実行するか、Node ターゲットのツーリングプロジェクトの一部としてコンパイルします。結果の JSON は、レビューのためにコミットしたり、CI アーティファクトとしてアップロードしたり、下流のテスト作成ツールで読み取ったりできます。正規かつコンテンツハッシュ化されているため、予期しないフォームコントラクトの変更はソース管理または CI で確認できます。
この宣言されたパスが最良の出発点です。静的構造をキャプチャし、任意のアプリケーションコードを実行せずに式コールバックを動的メタデータとして記録します。
4. Use a contract in Playwright
保存された JSON を信頼する前に検証し、必要なセマンティックノードを見つけ、その正確なロケーター候補の 1 つを使用します。標準の data-testid ロケーターの場合:
import { readFile } from 'node:fs/promises';
import {
parseFormContract,
type ContractNode,
type ModelPathSegment,
} from '@formly-contract/contract-schema';
function findNodeByPath(
nodes: readonly ContractNode[],
modelPath: readonly ModelPathSegment[],
): ContractNode | undefined {
for (const node of nodes) {
if (
node.modelPath.length === modelPath.length &&
node.modelPath.every((segment, index) => segment === modelPath[index])
) {
return node;
}
const nested = findNodeByPath(
node.arrayTemplate
? [...node.children, node.arrayTemplate]
: node.children,
modelPath,
);
if (nested) return nested;
}
}
const contract = parseFormContract(
JSON.parse(
await readFile('artifacts/form-contracts/claims.create.json', 'utf8'),
),
);
const claimantName = findNodeByPath(contract.nodes, ['claimant', 'name']);
const testId = claimantName?.locators.find(
(locator) =>
locator.strategy === 'testId' && locator.attribute === 'data-testid',
);
if (!claimantName || !testId) {
throw new Error('claimant.name has no exact data-testid locator');
}
await page.getByTestId(testId.value).fill('Ada Lovelace');実際のコンシューマーは通常、再帰的なノード検索とロケーター選択を共有の Playwright または Cypress ヘルパーに置きます。複合コントロールは複数のロケーターターゲットを公開できるため、ヘルパーは 1 つの Formly ノードが常に 1 つの DOM 要素にマップされると想定するのではなく、target で選択する必要があります。空のロケーター配列と診断は、欠落した証拠として処理する必要があり、発明されたセレクターで置き換えてはなりません。
5. Resolve dynamic behavior when needed
式が可視性、必須/読み取り専用状態、またはオプションリストを決定する場合は、合成シナリオを追加して compileFormContractScenario を呼び出します。その API を、アプリケーションの実際の Formly モジュールとカスタムタイプで構成された信頼できる Angular テスト/ビルド環境で実行します。意味のあるシナリオごとに 1 つのアーティファクトを生成し、合成モデルとフォーム状態データのみを使用します。
合成互換性ハーネス は、FormlyFormBuilder を取得するための完全な Angular TestBed セットアップを示しています。以下の詳細な API 例は、シナリオ呼び出しを示しています。
Why this is useful
大規模な Formly フォームは、ネストされたグループ、共有フラグメント、カスタムフィールドタイプ、式、動的選択肢、アプリケーションの規約から組み立てられることがよくあります。そのソースを繰り返し読むのは遅く、レンダリングされたページから推測すると脆いテストにつながります。
このプロジェクトは、小さく明確な境界を作成します:
Formly fields + synthetic scenario
|
safe contract projection
|
deterministic versioned JSON
|
E2E planning / agent inspectionコンシューマーは 1 つのコントラクトを検査して、次のような質問に答えることができます:
どのコントロールが存在し、どの順序か?
各コントロールはどのモデル値を編集するか?
どの値と検証境界が既知か?
選択リストは空、静的、動的、非同期のいずれか?
どのフィールドが非表示、必須、読み取り専用、無効になる可能性があるか?
どの
data-*、role、label、placeholder、DOM-ID ロケーター候補が利用可能か?どの事実が正確か、導出されたか、1 つのシナリオで解決されたか、まだ不明か?
Try this repository
前提条件:
Node.js
22.22.1pnpm
10.23.0
pnpm install --frozen-lockfile
pnpm demopnpm demo はパッケージスライスをビルドし、1 つの正規 JSON コントラクトを出力します。完全なリポジトリゲートを実行するには:
pnpm checkそのコマンドは、lint、すべてのテスト、パッケージと Angular の本番ビルド、デモのスモークテスト、ドキュメントチェックを実行します。
Extract declared form structure
Formly 設定があり、コールバックを実行せずに検査したい場合は、extractFormContract を使用します:
import { extractFormContract } from '@formly-contract/formly-adapter';
import type { FormlyFieldConfig } from '@ngx-formly/core';
const fields: FormlyFieldConfig[] = [
{
key: 'profile.name',
type: 'input',
props: {
label: 'Name',
required: true,
attributes: { 'data-testid': 'profile-name' },
},
},
];
const { contract, diagnostics } = extractFormContract({
formId: 'example.profile',
fields,
});このパスは純粋で非変更的です。式関数を呼び出したり、Observable にサブスクライブしたり、バリデーターを実行したり、Angular コンポーネントをレンダリングしたりしません。認識されたコールバックは動的ルールメタデータになり、サポートされていない動作は明示的な診断になります。返されるノードは、安定した ID example.profile::path:s_profile.s_name、モデルパス ['profile', 'name']、必須制約、正確な data-testid ロケーターを持ちます。
Resolve a synthetic scenario
必須、読み取り専用、無効、非表示、オプション、またはロケーター属性が Formly 式コールバックに依存する場合は、compileFormContractScenario を使用します:
import { inject } from '@angular/core';
import { FormlyFormBuilder } from '@ngx-formly/core';
import { compileFormContractScenario } from '@formly-contract/formly-adapter';
const builder = inject(FormlyFormBuilder);
const { contract, diagnostics } = compileFormContractScenario({
formId: 'example.profile',
builder,
createFields: () => createProfileFields(),
model: { contactMethod: 'email' },
formState: { readonly: false },
});これは信頼できるビルド/CI API です。アプリケーションの構成済み FormlyFormBuilder を使用するため、アプリケーションと Formly のコールバックが実行される可能性があります。モデルとフォーム状態は構造化クローン可能である必要があります。フィールドファクトリーまたはビルダーが実行される前に、両方がクローンされます。
ビルドされたフィールドツリーは、宣言された抽出と同じ許可リストを通過します。たとえば、動的オプションは、アプリケーションオブジェクトから任意のプロパティをコピーするのではなく、公開された label/value/disabled レコードに縮小されます。
このコンパイラーを MCP やその他の信頼できないリクエストハンドラーから直接公開しないでください。クエリレイヤーは、以前に生成されたコントラクトアーティファクトを読み取る必要があります。
Test locators
すべてのノードには順序付けられた locators 配列があります。アダプターは props.attributes からこれらの一般的な属性を自動的に読み取ります:
data-testiddata-test-iddata-testdata-cydata-pw
また、明示的な role、アクセシブルネーム、プレースホルダー、Formly フィールド ID の候補を保持することもできます。空の配列は信頼できるロケーターが見つからなかったことを意味します。アダプターは CSS や XPath を発明することはありません。
独自の命名規則を持つアプリケーションは、testIdAttributes を設定し、決定論的な deriveLocators コールバックを提供できます。コールバックは、ライブの Formly フィールドではなく、凍結された ID データのみを受け取ります。日付範囲などの複合ウィジェットに対して複数の名前付きターゲットを返すことができます。その出力は confidence: "derived" とマークされます。完全なコントラクトと例については、v0.3 ロケーター仕様 を参照してください。
Evidence model
コントラクトは 3 つの証拠レベルを分離して保持します:
Evidence | Meaning | Available now? |
| 提供された Formly 設定から安全に読み取る | はい |
| 1 つの合成シナリオに対して制御された Formly ビルドから読み取る | はい |
| 実際にレンダリングされたブラウザ DOM で見られる | スキーマ対応; キャプチャレイヤーは未実装 |
解決されたロケーターは、ブラウザで観測されたものとして暗黙的に提示されることはありません。同様に、不透明または非同期の動作は推測ではなく報告されます。
Supported contract information
スキーマ v0.3 は以下を表現できます:
順序付けられたコントロール、グループ、表示専用ノード、配列テンプレート
安定したセマンティックノード ID と累積モデルパス
Formly および一般的なセマンティックコントロールタイプ
ラベル、説明、プレースホルダー、JSON 安全なデフォルト、ラッパー
必須、最小/最大、長さ、文字列パターン、名前付き制約
静的および解決された公開オプション、および動的/非同期オプションソースメタデータ
文字列/ブール条件とコールバック/非同期動的ルールメタデータ
解決された非表示、読み取り専用、無効状態
複数の名前付きターゲットを含む、正確および導出されたロケーター候補
決定論的な診断、正規 JSON、コンテンツハッシュ
Intentional limitations
フォームは明示的に提供する必要があります。アダプターは任意の TypeScript エクスポートやアプリケーションルートを検出しません。
宣言された抽出は、関数や関数ソースを決して評価しません。
シナリオコンパイラーは初期の制御された Formly ビルドを実行しますが、リモートオプションやライフサイクル駆動のブラウザ動作を待機しません。
Formly の
RegExpパターンは診断されます。v0.3 は文字列パターンのみを表現します。カスタムウィジェットアクションとバリューコーデックはまだモデル化されていません。
このプロジェクトは現在、Cypress/Playwright テストを生成または実行しません。
本番 MCP サーバーやブラウザ観測レイヤーは含まれていません。
互換性は Angular
20.3.29と Formly6.1.8の組み合わせで証明されており、すべての Angular/Formly の組み合わせではありません。npm 公開とリリース自動化はまだ含まれていません。
Synthetic test application
Angular テストアプリケーションには、ネイティブおよびカスタムフィールド、ラッパー、バリデーター、拡張機能、プリセット、式、検証、リピーター、不透明な動作、レガシー Formly v6 エイリアスをカバーする 12 の発明されたフォームが含まれています。
pnpm app:servehttp://127.0.0.1:4200/ を開き、カタログからフィクスチャを選択します。
職場のフォームとデータは、プライベートな作業リポジトリに残す必要があります。プライベートフィクスチャモジュールは、TestFormDefinition を実装し、TEST_FORM_GROUPS を通じてグループを登録できます。職場のラベル、識別子、オプション、ルールをこの公開プロジェクトにコピーすることはありません。
Repository layout
packages/
contract-schema/ Versioned DTOs, validation, canonical JSON, and hashing
formly-adapter/ Declared extraction and trusted Formly scenario builds
fixtures/
synthetic-form/ Public golden form and real-builder compatibility fixture
apps/
demo-cli/ Prints the deterministic golden contract
formly-test-app/ Browser-rendered Angular/Formly fixture catalog
docs/ Specifications, ADRs, delivery plans, and evidenceRoadmap
意図された提供パスは次のとおりです:
Form Contract packages (current)
|
read-only MCP queries
|
typed E2E intent
|
deterministic Playwright/Cypress drivers
|
browser observation and parity checks将来のレイヤーは不変のコントラクトを消費する必要があります。Angular の実行、任意のコールバック評価、セレクターの発明を日常的なエージェントリクエストに移すべきではありません。
Documentation
コントリビューションとセキュリティ
コントリビューションを歓迎します。参加する前にCONTRIBUTING.mdと 行動規範をお読みください。セキュリティの問題は SECURITY.mdに記載されている非公開のプロセスを通じて報告してください。
このプロジェクトはMITライセンスの下で提供されています。
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Live React design-system APIs, patterns, and code validation so AI agents build real UI, not slop.
Machine-native capabilities with explicit contracts and machine-readable commerce.
Define, ship & query your analytics tracking from one source of truth, trusted by humans and agents.
API governance for AI agents. Detects breaking changes, scores blast radius, blocks unsafe calls.
Related MCP Servers
- AlicenseBqualityDmaintenanceExposes TypeScript Language Server Protocol functionality to AI agents, enabling them to query types at specific positions, find definitions and references, get diagnostics, run type tests, and type-check inline code just like in an IDE.91463MIT
- FlicenseAqualityDmaintenanceA clone-and-own MCP server that exposes OpenAPI/Huma contract intelligence to AI agents by turning API specifications into deterministic endpoint metadata, schemas, validation facts, and TypeScript declarations.6
- FlicenseAqualityDmaintenanceEnables AI agents to query component governance rules, validate component props, and generate development prompts for questionnaire editors.4
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to browse, read, compare, and validate OpenAPI contracts for providers and consumers.1MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/dills122/formly-contract'
If you have feedback or need assistance with the MCP directory API, please join our Discord server