CVSmia - User Guide
This page describes how to use CVSmia to build and save a tailored resume based on source data in JSONResume format.
Quick Example Flow With English Sample Data
This flow shows the simplest way to get started with the English sample resume that the app places in Documents\Solsem Consulting\CVSmia.
1. Start the app and check the tabs
On startup, the app opens in Customizer, and Validation is visible as its own tab from the start.

2. Open the English sample resume
Press Ctrl+O or choose Customizer -> Open, then open sampleresume_en.json.

3. Review the source data in the left tree
After the file is loaded, the jsonresume sections appear in the left-hand Sourcedata tree. In the screenshot below, the root node is expanded so you can see the sections included in the sample data.
You can also type text into the filter field above Sourcedata and press Filter to show only matching nodes together with the surrounding tree context.

4. Build a first tailored resume
For a quick first test, hold Ctrl and click the root node resume in the left tree. This copies the full sample resume to the right side. In normal use, you can instead Ctrl-click or drag individual sections to build a more targeted version.

5. Open the tailored resume in viewer
Once you have content in the right tree, open the viewer with Ctrl+P or the menu option that opens the viewer with data. The viewer shows the tailored resume in a print-friendly layout.

6. Print to PDF from viewer
When the viewer is open, press Ctrl+P in the browser and choose Save as PDF or a PDF printer such as Microsoft Print to PDF. The print dialog belongs to the browser, so the exact labels can vary slightly.

After that, you can save the PDF to the folder you want, or continue removing, renaming, or saving JSON content from the right tree.
Module Overview With Screenshots
The screenshots below show the remaining modules in the application. Some of them require a license before the tab becomes visible.
7. Validation
Use Validation when you want to check JSON against the schema, inspect errors by path/line, and edit the content before saving again.

8. AI-Customizer
AI-Customizer is a dedicated workspace for selecting relevant resume content against a job ad with AI assistance. It combines source data on the left, the AI-tailored resume on the right, and the job-ad input below.

9. JsonResumeConverter
Use JsonResumeConverter when you want to load raw text or another source and convert it into jsonresume, with AI attempted first and a local fallback if needed.

10. Matcher
Matcher lets you load both a resume and a job description and run matching in its own module without changing the trees in Customizer.

11. Cognitive
Cognitive is the module for language suggestions and rewriting. Use it when you want help improving or varying text content.

What is CVSmia?
CVSmia lets you:
- open source data (left tree),
- build a tailored resume by selecting content (right tree),
- save the result in an implemented export format (typically JSONResume, and Teamtailor when licensed),
- preview in viewer and validate against schema.
Typical workflow
- Open source data with
Ctrl+O. - Optionally filter the source data with the text field above the left tree when you want to narrow large datasets.
- Add content from left to right by drag-and-drop or
Ctrl+click. - Edit right-tree nodes where allowed (
F2rename,Deleteremove). - Save with
Ctrl+S. - Preview in viewer with
Ctrl+P(with data) orCtrl+Shift+V(viewer only). - Print to PDF from viewer with
Ctrl+Pin the browser.
Validation
Use the Validation tab to:
- run validation,
- inspect errors (path/line/message),
- copy errors,
- edit JSON,
- save corrected content.
If you open an invalid file it is marked as pending in Validation until fixed and saved.
Matcher
- The Matcher tab now includes a dedicated tree view with the JSONResume data used for matching.
- In the
Matchmenu, you can chooseOpen CV…to load a CV andOpen JD…to load a job description before running match. - Loading from
Matchdoes not modify theCustomizetrees. - Loading source data in
Customizealso does not updateMatcherautomatically. - After each run, Matcher now shows recommended next steps, such as which requirement needs stronger coverage or which existing resume evidence should be highlighted.
- When licensed,
AI-Customizeris shown as tab number 2.
Shortcuts
Ctrl+O: Open fileCtrl+S: Save tailored resumeCtrl+P: Open viewer with dataCtrl+Shift+V: Open viewerCtrl+Shift+O: Read from GitHub (wherever that menu action exists)Ctrl+,: SettingsF1: Open local helpAlt+F4: Exit the app (consistent across module menus likeCustomize,AI-Customizer,Validation,Converter,Cognitive, andMatch).Delete: Remove selected node in right treeF2: Rename selected editable node in right tree- Module menus now use the same shortcuts for equivalent actions (for example
Open=Ctrl+O,Save=Ctrl+S,Open viewer with data=Ctrl+Pwhere available).
Tips
- Keep one rich master resume in source data and make targeted variants in the right tree.
- Run validation before sharing/publishing.
Machine-readable license manifest
- The app exposes supported license modules in
license-modules.jsonin the application folder. - The source file lives at
src/CVSmia.Licensing/license-modules.json. - The file uses the generic protocol format with
protocolVersion,application, andmodules[].id. - The file is built from
src/CVSmia.Licensing/EnumAppModules.cs, so update the enum and build the project when the supported module set changes. Noneis intentionally excluded from the manifest.
Optional local telemetry
- Telemetry is off by default and must be enabled explicitly in
settings.jsonorappsettings.jsonwithSettings:TelemetryEnabled = true. - When enabled, the app writes local events to
%APPDATA%\Solsem Consulting\CVSmia\telemetry.ndjsonunlessSettings:TelemetryStoragePathis set. - The current event set covers app startup and the startup license-check result.
- Raw customer and license identifiers are not written to this telemetry file.
Startup license call-home
- Paid licenses can now be verified against SentinelCore during startup when
LicenseCallHomeis configured inappsettings.json. - The same call-home flow is also used when a paid license is installed or reloaded from the app, so the active license is checked consistently against SentinelCore.
- The first rollout uses
ObserveOnly. This means a valid local paid license still starts on network failure even if the lease cache is missing, but the event is logged clearly. - Trial remains local through
trial.datand Registry. Trial does not call home. - If a paid license file exists but is locally invalid, the app still does not fall back to trial.
- If SentinelCore rejects the paid license online, paid startup is rejected with no fallback to trial.
- On network failure, the app attempts to use a local lease cache in
%APPDATA%\Solsem Consulting\CVSmia.
Configuration example:
{
"LicenseCallHome": {
"Enabled": true,
"Mode": "ObserveOnly",
"BaseUrl": "https://sentinelcore.example.no/",
"VerifyTimeoutSeconds": 5,
"MetadataRefreshHours": 24,
"LeaseCacheFileName": "sentinelcore-lease.json",
"InstallationIdFileName": "installation-id.json"
}
}
GitHub as a Resume Source
- Use the
Read from GitHubmenu item when you want to load resume data from GitHub. - The menu item is available in
Customize,JsonResumeConverter,AI-Customizer, andMatcher. - Before the menu item is enabled, configure GitHub in
Settingswith either aTokenorUsername and password. - GitHub credentials are stored encrypted locally per user.
- When you select
Read from GitHub, a GitHub browser dialog opens so you can browse accessible repositories, choose a branch, and navigate to the file you want. - You no longer need to paste a raw GitHub URL manually.
- Regular local file loading via
Openis still available as before. - GitHub menu items stay disabled until the required GitHub credentials are configured.
- Token authentication is recommended for github.com.
jsonresume conversion and AI
JsonResumeConverterattempts AI conversion first.JsonResumeConverteruses the same AI settings as AI Customizer (AiEnabled,AiProvider,AiModel,AiEndpoint) fromsettings.json/appsettings.json.JsonResumeConverteruses the same provider resolver as AI Customizer; the selected provider/model in settings is used directly (including Gemini, Anthropic and Ollama), with local fallback on failure.JsonResumeConverternow follows the same AI integration pattern as AI Customizer: the panel calls a dedicated AI assistant service, while the converter module only handles AI-attempt + local fallback.JsonResumeConverternow shows in its title whether the current result came from AI or from local fallback.Validationalways runs local schema validation first, then attempts an AI explanation in its own prompt mode (ValidationAssistant) when validation finds errors.- If AI is disabled, the API key is missing, the selected provider is unsupported, or the AI call fails,
Validationnow shows a short status that local fallback is being used. Validationnow also shows local fix suggestions in a dedicatedSuggestioncolumn for common issues such as missing fields, invalid dates, and type mismatches.- The Validation summary area also highlights concrete suggestions worth fixing first.
- The app status bar now gives clearer next-step guidance after loading source data, matching, validation, save, and preview actions.
- OpenAI-compatible calls (payload, auth and response parsing) are moved to the shared
CVSmia.Ailibrary, used by both AI Customizer providers andJsonResumeConverter. - Prompt and instruction building remain module-specific:
JsonResumeConverteruses its own prompt builder (IJsonResumePromptBuilder) and does not share domain instructions across modules. - AI is used when a valid API key is available (
OPENAI_API_KEYor stored key in%APPDATA%\Solsem Consulting\CVSmia\ai-api-key.dat). - In AI Customizer, the
Customize (ask AI)menu item is disabled whenAiEnabledis off or when no stored API key exists. - If AI capability is unavailable or the AI call fails, the module automatically falls back to the local heuristic converter.
AI-CustomizerandAI Assisted CV Manipulatornow use the same standard messages as the other AI flows when AI is disabled, the API key is missing, or the selected provider is unsupported.- If invalid JSONResume is opened in AI-Customizer (
Open source data), the file is routed to the Validation module for review/fix. - When Validation saves/fixes pending JSON, data is sent back to the same module it came from (Customize or AI-Customizer).
- AI-Customizer now has a dedicated menu option to load job-ad text directly into the job-ad text field.
Open JDin AI-Customizer always loads raw text and does not route through the Validation module.- Model instructions are externalized in
prompts/jsonresume-extract.no.jsonusingsystemInstructionanduserTemplate.
Change AI instructions without rebuilding
You can change AI system instructions and prompt templates without recompiling:
- Install-level defaults: edit
ai-prompts.jsonin the app folder (same location asCVSmia.exe). - Per-user override: create/edit
%APPDATA%\Solsem Consulting\CVSmia\ai-prompts.override.json.
When to use which:
ai-prompts.json: change default behavior for the installation.ai-assisted-cv-manipulator-instructions.json: control which predefined instructions are shown inAI Assisted CV Manipulator.
AI Assisted CV Manipulator
AI Assisted CV Manipulator is a dedicated module for free-form AI processing of CV data.
- This module requires its own paid license and is hidden unless the module entitlement is included.
- Paste CV data into the left text box.
- Use
Ctrl+Oor theOpenmenu item to load source data directly into the left text box. - Enter your own instruction in the middle column or choose a predefined instruction from the dropdown.
- Click
Executeto send both the instruction and the CV data to the selected AI model. - The result is shown in the right text box.
- Use
Save to fileto save the content from the right text box. - Use
Edit instructionsto open and save the JSON list that controls the dropdown directly from the module.
Predefined instructions are loaded from ai-assisted-cv-manipulator-instructions.json in the application folder. The shipped file uses resource keys, but you can also provide explicit displayName and instruction values directly in the JSON file if you want custom presets.
The default list includes summary, skills extraction, role profile, conversion to jsonresume, translation to English, translation to Norwegian Bokmal, and a quality check for missing information.
ai-prompts.override.json: let one user override locally without changing installed files.
Important:
- Use valid JSON.
- Keep required tokens in templates:
- matching template:
{{jobDescription}}and{{resumeElements}} - customizer template:
{{jobAdText}},{{maxSelections}}and{{minConfidencePercent}} - validation template:
{{validationIssues}}and{{resumeJson}}
- matching template:
- Tone-specific system instruction can also be overridden via
SystemInstructionByTone.ValidationAssistant. - If a file is missing or invalid, the app falls back to built-in defaults.
AI Customizer confidence threshold
- AI Customizer now uses both max selections and a minimum confidence percent.
AiCustomizeMinConfidencePercent(0-100, default 60) controls which AI picks are included.- Items with a reported
confidencebelow the threshold are filtered out before insertion. confidenceis interpreted both as percent (0-100) and decimal (0-1), so values like82and0.82are treated the same.- To receive confidence values, the prompt format must request
selected[].confidence; the system instruction is now aligned to follow the output format from the user prompt. - AI Customizer now uses a dedicated provider prompt mode (
CustomizerSelection) so customizer output format is not overridden by the genericmatchedIdstemplate. - After AI extraction, a summary is shown with how many nodes had
confidenceand how many did not. - Hover over a node in the right tree (tailored CV) to view node-specific AI confidence when available.
- Nodes in the right tree are also color-coded by confidence (high = green, medium = yellow, low = red).
- Confidence color is applied to the node area itself (not the full row background).
- For truncated/incomplete AI JSON output, AI Customizer now avoids parsing the full response as JSON and goes directly to robust fallback extraction of
id/confidencefrom loose text. - For OpenAI/Azure OpenAI, AI Customizer now uses JSON mode (
response_format: json_object) and a higher max token limit in customizer calls to reduce truncated responses. - AI Customizer now applies a two-pass selection strategy for better precision when many nodes are suggested: pass 1 gathers a broad candidate set, pass 2 reranks only candidates and returns top
maxSelections. - Manual drag-and-drop is now supported both ways in AI Customizer: drag from left to right to add, and drag from right back to left to remove from
AI-customized CV. - In the right tree, the selected node can also be removed with the
Deletekey.