This document describes how to add a DialogQCA product dialog. DialogQCA is a DialogForge product repository, so DialogQCA owns its QCA dialogs, menu entries, capabilities, translations, runtime profile hooks, and product tests.
Do not add DialogQCA dialogs to the DialogForge shared dialog tree. Start DialogForge with this repository selected when you want the development import workflow to write DialogQCA source files.
Current DialogQCA dialogs live under:
dialogs/r/<dialog-id>/
dialog.json
actions.js
The registry is:
dialogs/dialogs.json
New imported packages may use the provider bucket from the package metadata. For R-specific dialogs, prefer the canonical provider bucket:
dialogs/r/<dialog-id>/
If you are editing an existing DialogQCA dialog, keep it in its current directory unless you are deliberately moving and updating the registry, menu/tests, and any references together.
<dialog-id> should match properties.name in dialog.json. Use a stable
identifier-style name: letters, numbers, and underscores, with no leading digit.
Existing DialogQCA examples include calibrate, truthTable, minimize,
xyplot, and venn.
Create or edit the dialog in DialogCreator and save it as a .dc.zip package.
The package is the exchange format. It must not be replaced by a loose .json
file.
The package should contain:
dialog.json;actions.js;- optional dialog-local support files.
When imported in product development mode, DialogForge unpacks the package into
the product dialog tree and updates dialogs/dialogs.json.
For a new R-specific dialog, create:
dialogs/r/<dialog-id>/
Then place:
dialogs/r/<dialog-id>/dialog.json
dialogs/r/<dialog-id>/actions.js
Do not split one dialog across several unrelated folders.
Keep dialog-specific helpers inside the same dialog directory unless they are reused by multiple DialogQCA dialogs.
Add an entry to dialogs/dialogs.json.
For a new provider-bucket dialog:
{
"id": "exampleDialog",
"label": "Example dialog",
"owner": "products/DialogQCA",
"targetHome": "products/DialogQCA/dialogs/r/exampleDialog/",
"sourceFile": "r/exampleDialog/dialog.json",
"status": "source-imported",
"replacement": "Run through the DialogCreator-compatible DialogForge dialog runtime."
}sourceFile is the only path here that is resolved, and it is relative to the
dialogs/ directory.
Dialog package requirements use the shared structured contract. Declare the oldest compatible release when the dialog depends on functionality introduced in a particular package version:
{
"rPackages": [
{
"name": "examplePackage",
"minimumVersion": "1.2.0"
}
]
}minimumVersion is optional when package presence is sufficient. Do not use
string declarations or latest; DialogForge, DialogR, and DialogQCA migrate
this metadata contract together.
Set minimumVersionExclusive to true when the boundary is strict. Product
settings also provide centrally maintained constraints that are applied when a
dialog requests one of those packages, including dynamic dependencies.
The same structured array belongs in the source dialog's
properties.rPackageRequirements. DialogForge preserves source-owned
requirements and merges them with the product registry, retaining the stricter
boundary. In the Dialog Runtime Requirements window, authors can enter the
same rule as QCA > 3.25 or venn >= 1.13.
Use the oldest version known to provide the dialog's required behavior. Do not
use the currently installed version unless it is also the genuine compatibility
boundary. R versions are compared component by component, so 1.10.0 is newer
than 1.9.9, 1.0-10 is newer than 1.0-2, and 1.0 is equivalent to
1.0.0.
DialogForge checks the requirements against the active R runtime. A missing or too-old package blocks execution and shows the required and installed versions.
The WebR VFS download also regenerates
library/R/package-manifest.json from the packaged DESCRIPTION files. Run
npm run webr:manifest after replacing the local VFS pair without using the
download command.
DialogQCA menu entries live in:
menu/menu.json
Use type: "product-dialog" and set dialog to the dialog registry ID.
Choose the top-level menu by user workflow:
Datafor calibration and condition recoding;Analyzefor truth-table, inconsistency, and minimization workflows;Graphsfor plotting and diagram dialogs.
Example:
{
"id": "QcaExampleDialog",
"labelKey": "menu.root.analyze.example_dialog",
"label": "Example dialog",
"type": "product-dialog",
"dialog": "exampleDialog",
"capability": "qca.dialog.exampleDialog"
}id is the menu item ID. dialog is the dialog ID from dialogs/dialogs.json.
Keep them distinct.
Add a matching capability to:
capabilities/product-capabilities.json
DialogQCA capability names use this pattern:
qca.dialog.<dialog-id>
Example:
{
"capability": "qca.dialog.exampleDialog",
"label": "Example dialog",
"runtimePrerequisites": [
{
"provider": "r",
"kind": "package",
"name": ["QCA"]
}
]
}The capability entry describes the QCA feature and any explicit runtime prerequisites. Keep this entry in product language: the dialog name, its label, and the packages or provider-specific prerequisites it needs. DialogForge derives and validates its lower-level runtime requirements from the dialog package, product metadata, and runtime provider contract.
Most QCA dialogs should declare a QCA package prerequisite. Add venn,
admisc, or other packages only when that dialog actually needs them. Future
non-R runtime providers can use their own provider and prerequisite kind.
The menu item should have a stable labelKey. Add that key to each DialogQCA
locale file under:
i18n/*.json
Dialog-local labels and control text belong in the dialog package's dialog.json
i18n section. Product menu labels belong in DialogQCA locale files.
Dialog behavior belongs in actions.js when it is local to one dialog.
If the dialog needs QCA-specific behavior, such as calibration previews,
truth-table state, XY plot rendering, Venn rendering, or product external calls,
route through DialogQCA-owned product modules and existing dialog external-call
conventions. Do not call Electron IPC, DOM internals outside the dialog runtime,
or DialogForge private implementation files directly from actions.js.
If new shared DialogQCA dialog behavior is needed, add it as a product-owned helper and test it. Promote code to DialogForge shared code only when it is truly reusable outside DialogQCA.
DialogCreator is the preferred place to design and edit dialogs. If you inspect
or adjust a dialog.json file in VS Code, attach DialogForge's schema so the
editor can show field names, descriptions, and basic mistakes while you type.
For a DialogQCA checkout next to DialogForge, add this to .vscode/settings.json:
{
"json.schemas": [
{
"fileMatch": ["dialogs/**/dialog.json"],
"url": "../DialogForge/schemas/dialog.schema.json"
}
]
}If your folders are arranged differently, keep fileMatch the same and adjust
only the url so it points to DialogForge's schemas/dialog.schema.json.
DialogQCA still validates registered dialog files during npm run check and
when DialogForge stages the product.
Most DialogQCA dialog authors do not need the SDK. If you are adding a dialog, editing dialog labels, changing menu placement, or declaring package prerequisites, stay in the dialog, menu, capability, and locale files described above.
Use the SDK only when you edit DialogQCA's product wiring, especially:
bootstrap/productContribution.ts;- QCA-specific external calls;
- product-level runtime method calls;
- product-level console state chips, if DialogQCA adds them later.
The SDK gives TypeScript and editors the public DialogForge product contract.
It keeps DialogQCA code away from DialogForge private shared/ implementation
files.
From the DialogForge repository, build or refresh the SDK:
npm run sdk:coreThis creates the local package:
DialogForge/dist/sdk/core
DialogQCA's package.json should point @dialogforge/core at that local
package:
{
"devDependencies": {
"@dialogforge/core": "file:../DialogForge/dist/sdk/core"
}
}If your folders are not siblings, adjust the relative path so it points to the
same dist/sdk/core directory.
After changing or refreshing that dependency, run this from the DialogQCA repository:
npm installThen bootstrap/productContribution.ts can import the public SDK:
import {
PRODUCT_CONTRIBUTION_CONTRACT_VERSION,
type ProductContribution
} from "@dialogforge/core";
export const productContribution: ProductContribution = {
id: "DialogQCA",
dialogForgeProductContract: PRODUCT_CONTRIBUTION_CONTRACT_VERSION,
createDialogExternalCallHosts: function(context) {
return {
qca: createQcaExternalCallHostForSession({
executeRuntimeMethod: context.executeRuntimeMethod
}, "DialogQCA.dialog")
};
}
};When the contribution changes, check it from DialogQCA:
npm run checkThen start DialogForge with DialogQCA selected:
npm run dev:product -- /path/to/DialogQCAFor agents: use @dialogforge/core for product contribution types and the
contract version. Do not reintroduce imports from DialogForge private shared/
paths for this product boundary.
When DialogForge is started with this repository selected, menu customization's
Browse action imports .dc.zip packages into this repository. It should create
or update:
dialogs/<provider>/<dialog-id>/
dialogs/dialogs.json
Review those changes before committing. The UI can help place a menu item, but
the committed source of truth is still menu/menu.json, not a user-local menu
customization file.
After adding a dialog, run:
npm run checkFor rendered behavior, use the product electron dialog verifier when needed:
npm run verify:electron-dialogAlso check the relevant dialog-runtime tests under tests/dialog-runtime/.
If the new dialog adds product-specific external calls, previews, rendering, or
runtime-profile behavior, add focused product tests under tests/products/ or
tests/dialog-runtime/.
Before committing:
- the dialog directory contains
dialog.jsonandactions.js; dialogs/dialogs.jsonhas the dialog ID and correctsourceFile;menu/menu.jsonhas aproduct-dialogentry where DialogQCA users expect it;capabilities/product-capabilities.jsonhas the matching capability;- menu
labelKeyvalues exist ini18n/*.json; - runtime prerequisites are declared on the capability when needed;
- DialogQCA product tests cover any new non-trivial behavior.