A VS Code / Kiro IDE extension for editing Mongoose IDO Collection metadata
(ObjectStudioExport XML) through a friendly, visual UI instead of hand-editing deeply
nested XML.
Version 1.18.0. See CHANGELOG.md for release notes and DESIGN.md for the design and roadmap.
Features (v1)
- Visual custom editor for any
**/Collections/**/*.xml IDO file, with tabs:
- Properties — the primary working view: a sticky Identity bar (name, module,
ext-class, revision, inline-editable description), a read-only property grid
(# · Name · Binding badge · Class · Source) that filters, sorts and scrolls
independently, and a resizable, toggleable editor side panel that stays in view.
The panel edits every field with dropdowns/checkboxes, shows inline validation, has
Open ↗ buttons to jump to a referenced IDO, and a read-only inherited
PropertyClass section.
- Overview — edit identity / ext-class / revision fields.
- Tables — fully editable grid (alias, table, type, join) with add/delete rows.
- Properties — master–detail with binding badges, key markers, drag-to-reorder
(auto-renumbers
Sequence), add/delete, and a binding-aware detail form
(BOUND/DERIVED/UNBOUND/SUBCOLLECTION fields + PropertyAttributes) with enum dropdowns.
- Methods — editable method cards (name, type, transactional, stored proc, description)
with an editable parameter grid (seq, name, DB type/length/scale, in/out/message) and
add/delete for methods and parameters.
- IDO Outline — a second sidebar tree showing the structure of the active IDO
(Tables, Properties grouped by binding, Methods → parameters, Data Rules). Clicking a node
navigates the visual editor to that item.
- Labeled enums — "magic number" fields (MethodType, Binding, OperationType,
ActionType, comparison operators, …) render as dropdowns with human labels.
- Validation — semantic + intra-file reference checks surfaced as diagnostics
(Problems panel) and a live footer summary: required fields, invalid enum codes,
duplicate names, BOUND/DERIVED/SUBCOLLECTION requirements,
ColumnTableAlias must
match a real table alias, duplicate sequences, and more. A Fix all button in the Problems
panel applies safe default fixes for eligible errors (e.g. setting IsReadOnly on a property
targeted by a "Set Property Enabled" data-rule action).
- IDO Explorer — activity-bar tree of all collections grouped by module, with a
fuzzy Go to Collection… quick-pick.
_IDS variants are flagged.
- Base ⇄ _IDS compare — open a diff between a collection and its
_IDS sibling.
- PropertyClass editor —
**/PropertyClasses/**/*.xml files open in a dedicated visual
master–detail editor (list of PropertyClass definitions + a detail form covering the full
PropertyAttributes set from PropertyClass.xsd), with clean round-trip and validation.
A dedicated IDO Property Classes activity-bar panel (grouped by module) and the
IDO: Go to PropertyClass… quick-pick help you find and open them.
- Clean round-trip — writes are format-conformant (BOM, CRLF, 3-space indent,
self-closing empties) and schema-faithful. 98% of the real corpus round-trips
byte-for-byte; the rest are irregularly-indented files that get normalized by design.
- Always available: one-click Open as XML to drop to the raw text editor.
Configuration
| Setting |
Default |
Description |
mgIdo.collectionsGlob |
**/IdoMetadata/**/Collections/**/*.xml |
Files discovered for the explorer/index. |
mgIdo.metadataRoots / mgIdo.metadataRoot / mgIdo.mongooseMetadataRoot |
(empty) |
Explicit IDO metadata root folders to index (Collections + PropertyClasses). When all empty (default), the extension auto-detects metadata from the open workspace via collectionsGlob. |
mgIdo.fallbackDevRoot |
C:\\Development\\csi |
Fallback CSI dev root used only when no metadata-root setting is set and the open workspace has no IDO metadata. The extension then indexes <fallbackDevRoot>\\IdoMetadata and <fallbackDevRoot>\\Mongoose.submod\\IdoMetadata\\Mongoose. |
mgIdo.indentSize |
3 |
Indent width fallback. |
mgIdo.validateOnSave |
true |
Validate on save. |
mgIdo.openVisualByDefault |
true |
Open matching files in the visual editor by default. |
mgIdo.sequenceMode |
contiguous |
contiguous | preserve | gapped sequence numbering. |
mgIdo.formatScope |
document |
document | touched formatting scope (v1: document). |
mgIdo.referenceScope |
module |
module | workspace cross-reference resolution. |
mgIdo.sytelineInstallPath |
C:\Program Files\Infor\CSI |
Folder with AppMetadataTransport.exe used to import IDO XML for testing. Falls back to …\Setup\WinStudio and the dev …\Mongoose.submod\Setup\WinStudio. |
mgIdo.importConfig |
(empty) |
Target SyteLine configuration for imports (e.g. Demo_DALS). Prompted and saved here on first import if empty. |
mgIdo.bumpRevisionOnSave |
true |
On save of a changed IDO file, increment <RevisionNo> and stamp <RevisionDate> (local time). |
mgIdo.schemaCatalog |
(empty) |
Path to a JSON DB schema catalog { "Table": ["Col", …] }. When set, validation also flags Table names not in the schema and BOUND properties whose BoundToColumn isn't a real column of its table. |
Schema-aware validation (verify tables & columns)
Point mgIdo.schemaCatalog at a JSON file mapping each table to its columns; validation then
checks that every <Table Name> exists and every BOUND property's BoundToColumn is a real
column of its table (surfaced as warnings in the Problems panel). Generate the catalog from
INFORMATION_SCHEMA, e.g. with sqlcmd + a small transform:
sqlcmd -S localhost -E -d <YourDb> -h -1 -W -s "," -Q \
"SELECT TABLE_NAME + ',' + COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS" \
| awk -F, 'NF==2{printf "%s\t%s\n",$1,$2}' \
| node -e "const m={};require('readline').createInterface({input:process.stdin}).on('line',l=>{const [t,c]=l.split('\t');if(t&&c){(m[t]=m[t]||[]).push(c);}}).on('close',()=>process.stdout.write(JSON.stringify(m)))" \
> schema-catalog.json
Commands
- IDO: Open in Visual Editor / IDO: Open as XML
- IDO: Validate
- IDO: Go to Collection…
- IDO: Compare base ⇄ _IDS variant — native side-by-side XML diff
- IDO: Compare base ⇄ _IDS (structured) — a readable HTML report (themed tables) of what differs
(added / removed / changed properties, tables, methods, data rules), ignoring the revision stamp
- IDO: Analyze Cached Setting Impact… — cross-file report of every data rule (action/condition)
that reads a chosen cached setting, so you can see what breaks before renaming/removing it
- IDO: Analyze Data Rules (test plan) — writes
<IDO>.datarules.md: a test-plan analysis that
classifies every rule by REST-testability, renders trigger logic trees, lists environment
dependencies, and derives test scenarios (for automated MG API test generation)
- IDO: Import to SyteLine (for testing) — deploys the current IDO XML via
AppMetadataTransport.exe
- IDO: Test in MG REST Client — opens a pre-selected quick test form (Load/Update/Invoke/…) using the REST client's active profile, or Generate Data Rule Tests (calls
mgRestClient.generateDataRuleTests to build a test collection from this IDO's data rules); shown only when the jeking.mg-rest-client extension is installed
- SyteLine Dev Hub integration (shown only when the SyteLine Dev Hub extension is installed):
IDO: Open C# Entry Point (title-bar → jump to the IDO's C# entry-point code), IDO: Forms
Using This IDO (title-bar → every form that consumes the IDO), IDO: Trace Dependencies in Dev
Hub (title-bar → down-trace the IDO's C# entry point), and IDO: Trace GetService Roots
(right-click a method in the IDO Outline → trace that method's services)
- IDO: Enable XSD Validation (Red Hat XML) — binds the bundled official Mongoose
IDODefinition.xsd to **/Collections/**/*.xml so the Red Hat XML extension validates IDO files against the schema
- IDO: Rebuild Index
For other extensions (programmatic)
mgIdo.openIdoByName(name: string): Promise<boolean> — resolve an IDO by name via the
workspace index and open it in the visual editor; returns true if found. Hidden from the
Command Palette. Example:
const ext = vscode.extensions.getExtension('jeking.mg-ido-pro-editor');
await ext.activate();
const ok = await vscode.commands.executeCommand('mgIdo.openIdoByName', 'SLItems');
Read-only metadata API (used by MG REST Client to source IDO metadata from the workspace files
instead of live Mongoose REST queries — faster and works offline). Each returns undefined when the
IDO isn't found in the workspace, so the caller can fall back to REST. Activate the extension first.
| Command |
Returns |
mgIdo.api.getIdoNames() |
string[] — distinct IDO collection names in the workspace |
mgIdo.api.getMethods(ido, kind?) |
{ name, type }[] — kind='load' for custom-load (result-set) methods, else invokable |
mgIdo.api.getProperties(ido) |
{ name, isKey, readOnly, required, type }[] |
mgIdo.api.getMethodParameters(ido, method) |
{ name, direction, type }[] (direction: in/out/inout/message) |
mgIdo.api.getDataRules(ido) |
IdoDataRuleInfo[] — all data rules with active/inheritToUI/operationType (+label) and their actions / conditions / filters (each with decoded labels, e.g. ActionType → "Set Property Enabled") |
mgIdo.api.getDataRule(ido, ruleName) |
a single data rule by name (case-insensitive), or undefined |
mgIdo.api.analyzeDataRules(idoNameOrPath) |
{ markdown, spec } — the full Data Rule + property-validator test-plan analysis (accepts an IDO name or a file path), or undefined |
MCP server (for AI agents)
The extension ships a dependency-free MCP server (dist/mcp/server.js, stdio JSON-RPC)
that exposes the IDO engine to MCP-capable agents (e.g. Kiro). Register it with
IDO: Register MCP Server with Kiro (writes .kiro/settings/mcp.json, seeding
MG_IDO_ROOTS from your metadata-root settings); remove it with IDO: Unregister MCP
Server from Kiro. Tools:
| Tool |
Purpose |
ido_create |
Create a new IDO collection file at a path or in an existing folder (identity + optional initial tables/properties/methods/data-rules) — dry-run/apply, won't overwrite unless overwrite:true. |
ido_update |
Update an IDO's definition-level (identity) fields — dry-run/apply. |
ido_delete |
Delete the entire IDO collection file (dry-run/apply; distinct from ido_delete_item). |
ido_list_collections |
Discover IDOs under MG_IDO_ROOTS (name, module, AccessAs, _IDS, path). |
ido_get_model |
Full structured model (tables/properties/methods/data-rules) for one file. |
ido_get_property / ido_get_table / ido_get_method / ido_get_data_rule |
Fetch a single item by name. |
ido_list_property_classes |
List PropertyClasses discovered under MG_IDO_ROOTS (name, BaseClass, file). |
ido_validate |
Semantic + reference validation issues (schema-aware when MG_IDO_SCHEMA is set); pass checkReferences:true to also resolve cross-file INCOLLECTION/IDOMETHOD/Domain + cached-setting references against MG_IDO_ROOTS and flag dangling ones. |
ido_compare_ids |
Structured base ⇄ _IDS diff (summary + Markdown). |
ido_analyze_datarules |
Analyze data rules + property validators → a test-plan (Markdown/JSON spec): per-rule REST-testability class, trigger tree, scenarios, env deps. |
ido_get_cached_settings |
List an IDO's <CachedSetting>s (name + fields; ScopeLevel/SourceType decoded). |
ido_add_cached_setting / ido_set_cached_setting / ido_delete_cached_setting |
Cached-setting CRUD (by SettingName) — dry-run/apply. |
ido_analyze_cached_setting_impact |
Cross-file: every data rule that reads a cached setting (impact of renaming/removing it). |
ido_resolve_property_class |
Resolve a PropertyClass chain → effective attributes. |
ido_add_property / ido_set_property |
Add / edit a property (bindings, PropertyAttributes) — dry-run/apply. |
ido_reorder_property |
Move a property to a new position and renumber — dry-run/apply. |
ido_add_table / ido_set_table |
Add / edit a table (name, alias, type, join) — dry-run/apply. |
ido_add_method / ido_set_method |
Add / edit a method + parameters — dry-run/apply. |
ido_add_parameter / ido_set_parameter / ido_delete_parameter |
Method-parameter CRUD — dry-run/apply. |
ido_add_data_rule / ido_set_data_rule |
Add / edit a data rule + actions/conditions/filters — dry-run/apply. |
ido_add_rule_item / ido_delete_rule_item |
Add / delete a rule action/condition/filter — dry-run/apply. |
ido_rename_item |
Rename a property/table/method/data rule — dry-run/apply. |
ido_delete_item |
Delete a property/table/method/data rule by key — dry-run/apply. |
ido_import |
Deploy/import an IDO into a SyteLine config via AppMetadataTransport.exe — dry-run/apply (uses MG_SL_INSTALL / MG_IMPORT_CONFIG). |
ido_import_changed |
Import all IDOs changed vs a base git ref (batch deploy) — dry-run/apply. |
ido_sync_to_ids |
Copy an item into the _IDS sibling — dry-run/apply. |
ido_bump_revision |
Increment RevisionNo + stamp RevisionDate — dry-run/apply. |
ido_format |
Canonically re-serialize a file — dry-run/apply. |
Read tools are auto-approved; the write tools default to a dry-run and only touch disk
with apply:true.
Architecture
src/
model/ XML tree (parse/serialize), typed projection, enums, sequence, edits
validation/ semantic + reference validation
editor/ CustomTextEditorProvider (hosts the webview, applies edits)
explorer/ workspace index + collections tree + active-IDO outline tree
webview/ UI (framework-free TS) + host/webview message protocol
extension.ts activation: editor, explorer, commands, diagnostics
media/ webview.css + activity-bar icon
test/ node:test suites (core + corpus round-trip)
The open TextDocument is the single source of truth. Webview edits post typed messages;
the host applies them to the XML tree, re-serializes canonically, and replaces the document
via a WorkspaceEdit — so text view, undo/redo, and external edits all stay in sync.
Development
npm install
npm run build # bundle extension + webview (esbuild)
npm run watch # rebuild on change
npm run typecheck # tsc --noEmit
npm test # compile + run node:test suites
Run the extension: open this folder in VS Code / Kiro and press F5 (Extension
Development Host), then open any IDO collection XML.
Tests
test/roundtrip.test.ts — runs against the real corpus (set MG_CORPUS to override the
path, MG_SAMPLE to change the file count). Hard gates: semantic equality (no data
loss) and idempotency (no formatting drift); plus a byte-exact rate metric.
test/core.test.ts — enum catalog, model projection, sequence renumbering, edit ops, and
validation.
test/edits.test.ts — full CRUD edit operations (add/edit/delete for properties, tables,
methods, parameters) with serialization-stability checks.
test/webview.test.ts — jsdom smoke test that runs the real bundled webview, asserts the
Canvas renders, and that inline edits / row-expand / add emit the correct messages.
Status / Roadmap
This is the MVP. Planned next: cross-file reference go-to-definition, the guided DataRule
builder, canvas relationship lines + drag-drop binding conversions, _IDS sync, and editors
for the sibling constructs (PropertyClass, Form/ComponentClass/Validator). See DESIGN.md.
| |