Skip to content

feat(editor): load strict contract bundles#12

Merged
intel352 merged 2 commits into
masterfrom
impl/strict-contract-bundle-ui
Apr 27, 2026
Merged

feat(editor): load strict contract bundles#12
intel352 merged 2 commits into
masterfrom
impl/strict-contract-bundle-ui

Conversation

@intel352

Copy link
Copy Markdown
Contributor

Summary

  • add editor bundle public types and bundle-aware schema loading
  • load strict contract bundles through a new onEditorBundleRequest host callback while preserving legacy schema/plugin callbacks
  • store contracts/messages/YAML schemas and surface contract metadata in the property panel for module and step owners

Verification

  • git diff --check HEAD~2..HEAD
  • npx tsc --noEmit
  • npm test (44 files / 4107 tests)
  • npm run build
  • npm run lint currently blocked by repo ESLint 9 config migration: missing eslint.config.(js|mjs|cjs)

Review

  • Spec review: PASS
  • Antagonistic code review: initial BLOCK resolved; final PASS

Depends on Workflow PR #501, merged as 00dce7ba96af43ca3d5a125f8b223d89fb0c49a2.

Copilot AI review requested due to automatic review settings April 27, 2026 07:05
@intel352 intel352 merged commit 8ec3f7f into master Apr 27, 2026
6 checks passed
@intel352 intel352 deleted the impl/strict-contract-bundle-ui branch April 27, 2026 07:07

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds support for loading a canonical “editor contract bundle” (strict contracts + schemas + metadata) via a new host callback, while keeping legacy schema/plugin loaders as a fallback. This extends schema state in the editor store and surfaces contract metadata in the property panel for modules and pipeline steps.

Changes:

  • Introduces onEditorBundleRequest and new public bundle/contract/message/schema types for the editor host interface.
  • Extends moduleSchemaStore to load/normalize bundles (modules, steps, coercion rules, contracts/messages, YAML schemas) and provides lookup helpers.
  • Displays contract metadata in the Property Panel and adds/updates tests for bundle loading and UI rendering.

Reviewed changes

Copilot reviewed 7 out of 9 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/types/editor.ts Adds public types for editor contract bundles, contracts/messages, and YAML schemas, plus the new host callback prop.
src/stores/moduleSchemaStore.ts Adds bundle-aware schema state, bundle loading/normalization integration, and contract/message/schema lookup helpers.
src/stores/moduleSchemaStore.contracts.test.ts New tests covering contract bundle loading and overlay behavior.
src/generated/load-schemas.ts Adds normalizeEditorContractBundle to safely default missing bundle sections.
src/generated/load-schemas.test.ts Tests for bundle normalization behavior.
src/components/properties/PropertyPanel.tsx Surfaces contract metadata for selected module/step nodes.
src/components/properties/PropertyPanel.test.tsx Tests contract metadata rendering for module and step nodes.
src/components/WorkflowEditor.tsx Loads editor bundle via onEditorBundleRequest with fallback to legacy schema callbacks.
src/components/WorkflowEditor.test.tsx Tests bundle-preferred loading and legacy fallback scenarios.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +118 to +124
const [schemaData, pluginData] = await Promise.all([
onSchemaRequest ? onSchemaRequest() : Promise.resolve(null),
onPluginSchemaRequest ? onPluginSchemaRequest() : Promise.resolve(null),
]);
if (cancelled) return;
if (schemaData) loadSchemas(schemaData.modules as Parameters<typeof loadSchemas>[0]);
if (pluginData) loadPluginSchemas(pluginData);

Copilot AI Apr 27, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

loadLegacySchemas uses Promise.all for onSchemaRequest and onPluginSchemaRequest. If either callback rejects, the whole await rejects and you end up loading neither schema set (and you can also get an unhandled rejection from the effect). Consider handling these independently (e.g., Promise.allSettled or separate try/catch per callback) so one failing callback doesn’t prevent the other from being applied.

Suggested change
const [schemaData, pluginData] = await Promise.all([
onSchemaRequest ? onSchemaRequest() : Promise.resolve(null),
onPluginSchemaRequest ? onPluginSchemaRequest() : Promise.resolve(null),
]);
if (cancelled) return;
if (schemaData) loadSchemas(schemaData.modules as Parameters<typeof loadSchemas>[0]);
if (pluginData) loadPluginSchemas(pluginData);
const [schemaResult, pluginResult] = await Promise.allSettled([
onSchemaRequest ? onSchemaRequest() : Promise.resolve(null),
onPluginSchemaRequest ? onPluginSchemaRequest() : Promise.resolve(null),
]);
if (cancelled) return;
if (schemaResult.status === 'fulfilled') {
const schemaData = schemaResult.value;
if (schemaData) loadSchemas(schemaData.modules as Parameters<typeof loadSchemas>[0]);
} else {
console.warn('Failed to load legacy schemas:', schemaResult.reason);
}
if (pluginResult.status === 'fulfilled') {
const pluginData = pluginResult.value;
if (pluginData) loadPluginSchemas(pluginData);
} else {
console.warn('Failed to load legacy plugin schemas:', pluginResult.reason);
}

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants