Configuration Wizards
Plugins can expose their own CLI configuration flow with a declarative wizard. The plugin repository keeps the questions and the JSON shape its job reads; Divekit CLI provides the terminal UI and writes the result where the plugin job finds it.
The intended workflow for a course maintainer is:
divekit plugin add maven
divekit plugin configure maven
divekit plugin configure <suite> runs the wizards of the suite’s enabled
plugins in one session, in plugin order; divekit plugin configure <suite>/<plugin> runs one of them. Divekit reads each wizard at the plugin
release the course has locked, so the questions always match the plugin
version that evaluates the answers. A plugin without a wizard simply
contributes no questions.
Plugin Manifest
Declare the wizard path in the plugin’s manifest.json:
{
"version": "1.0",
"id": "jacoco-pit",
"kind": "plugin",
"name": "JaCoCo and PIT",
"description": "Coverage and mutation thresholds for the classes a course selects.",
"configuration": {
"wizard": "configure.wizard.json"
}
}
The path is relative to the plugin repository and has to stay inside it.
Suites do not carry wizards; the suite only provides the one-session command.
Flat pre-suite plugins still declare the same block in their plugin.json
and are run with divekit plugin configure <plugin>.
Wizard File
A minimal wizard looks like this:
{
"version": "1.0",
"title": "Example Plugin",
"description": "Configure example checks.",
"result": {
"path": "config.json",
"schemaVersion": 1
},
"steps": [
{
"id": "checks",
"title": "Checks",
"fields": [
{
"key": "coverage.line",
"type": "percent",
"label": "Line coverage",
"description": "Required line coverage for the plugin check.",
"default": 0.8
},
{
"key": "classesToInclude",
"type": "stringList",
"label": "Classes to include",
"default": ["src/main/java"]
}
]
}
]
}
result.path defaults to config.json. Relative paths are resolved below
.divekit/plugins/<suite>/<plugin>/, the plugin’s runtime-ID directory. Paths
that start with / are resolved from the evaluation repository root. Parent path segments such as .. are accepted and
therefore allow a plugin to intentionally write elsewhere in the evaluation
repository. result.schemaVersion is optional; when it is set, Divekit writes it
as top-level schemaVersion in the generated JSON.
When a configuration file already exists, divekit plugin configure uses those
values as editable initial values. Missing values fall back to wizard defaults
or placeholders.
For repeatable setup, run the wizard with --yes:
divekit plugin configure maven/jacoco-pit --yes
In this mode Divekit does not open the terminal UI. It preserves existing
configuration values and applies wizard defaults for missing values. Required
text, path, and numeric fields still need an existing value or a wizard default.
Optional percent, number, and integer fields with an empty value are left
unset instead of being written as zero; empty stringList and multiSelect
fields are written as empty lists.
The CLI stores the collected values as JSON. Dotted field keys create nested
objects, so coverage.line becomes:
{
"coverage": {
"line": 0.8
}
}
Supported field types are string, text, stringList, path, pathList,
percent, number, integer, boolean, select, multiSelect, and
objectList.
text renders a multiline prompt and stores a string. path and pathList
store path-like strings. They support local tab completion for concrete paths,
but glob-like patterns such as * and ** are accepted unchanged and interpreted
by the plugin.
objectList renders repeatable object entries and stores an array of JSON
objects. Its fields are regular wizard fields with keys relative to each list
entry. Dotted child keys create nested objects inside that entry:
{
"key": "tasks",
"type": "objectList",
"label": "Task",
"required": true,
"fields": [
{ "key": "name", "type": "string", "label": "Name", "required": true },
{ "key": "coverage.lineCoverage", "type": "percent", "label": "Line coverage" },
{ "key": "classesToInclude", "type": "stringList", "label": "Classes to include" }
]
}
This writes:
{
"tasks": [
{
"name": "unit",
"coverage": {
"lineCoverage": 0.8
},
"classesToInclude": ["de.thkoeln.example.*"]
}
]
}
fields is only valid on objectList fields. Nested objectList fields are
not supported; use dotted child keys for nested objects within each entry.
When a configuration already contains an objectList, reconfiguration asks for
each existing entry whether it should be edited, kept unchanged, or removed.
After existing entries have been processed, the wizard can append additional
entries. A required objectList must contain at least one entry.
select and multiSelect fields declare options:
{
"key": "report.mode",
"type": "select",
"label": "Report mode",
"default": "summary",
"options": [
{ "value": "summary", "label": "Summary" },
{ "value": "detailed", "label": "Detailed" }
]
}
Configuration Result
With the default result.path, the plugin configuration is available inside the
evaluation repository at:
.divekit/plugins/maven/jacoco-pit/config.json
Divekit writes that file into the origin repository’s eval authoring tree:
.divekit/eval-pipeline/eval/.divekit/plugins/maven/jacoco-pit/config.json
.divekit/distributions/<distribution>/eval-pipeline/eval/.divekit/plugins/maven/jacoco-pit/config.json
When the eval repository is generated, the plugin job reads:
.divekit/plugins/maven/jacoco-pit/config.json
The generated job passes the two halves of the runtime ID as
DIVEKIT_SUITE_ID and DIVEKIT_PLUGIN_ID, so a plugin can build that path
without hardcoding its suite.
See Plugin Configuration JSON for a complete example of the generated plugin-owned configuration file.
Boundaries
The wizard describes the user interface and the JSON shape. Plugin-specific
meaning stays in the plugin. For example, JaCoCo PIT decides how coverage
thresholds, include paths, exclude paths, and task success rules affect its
reports. Manual report overrides are Divekit-owned and are managed with
divekit plugin override; they should not be modeled as plugin-owned wizard
settings.
The CLI does not execute plugin code while asking questions. It only fetches the wizard from the locked plugin release, prompts for values, and writes the result JSON.