hoi4-agent-tools 4.0.0 → 4.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +27 -53
  3. package/dist/hoi4_agent_tools/core/condition-evaluator.js +18 -0
  4. package/dist/hoi4_agent_tools/core/job-worker-host.js +115 -27
  5. package/dist/hoi4_agent_tools/core/job-worker.js +7 -2
  6. package/dist/hoi4_agent_tools/core/temporary-directories.js +293 -0
  7. package/dist/hoi4_agent_tools/core/worker-exit.js +80 -0
  8. package/dist/hoi4_agent_tools/gui/assets.js +3 -0
  9. package/dist/hoi4_agent_tools/gui/dds.js +8 -4
  10. package/dist/hoi4_agent_tools/gui/layout.js +45 -5
  11. package/dist/hoi4_agent_tools/gui/native-state.js +244 -0
  12. package/dist/hoi4_agent_tools/gui/renderer.js +12 -7
  13. package/dist/hoi4_agent_tools/gui/source-graph.js +17 -4
  14. package/dist/hoi4_agent_tools/gui/studio.js +33 -21
  15. package/dist/hoi4_agent_tools/mcp/prompts/probability.js +2 -2
  16. package/dist/hoi4_agent_tools/mcp/server/instructions.js +1 -1
  17. package/dist/hoi4_agent_tools/mcp/tools/analysis.js +8 -8
  18. package/dist/hoi4_agent_tools/mcp/tools/event.js +3 -3
  19. package/dist/hoi4_agent_tools/mcp/tools/focus.js +5 -5
  20. package/dist/hoi4_agent_tools/mcp/tools/gui.js +6 -6
  21. package/dist/hoi4_agent_tools/mcp/tools/job.js +4 -4
  22. package/dist/hoi4_agent_tools/mcp/tools/map.js +4 -4
  23. package/dist/hoi4_agent_tools/mcp/tools/probability.js +4 -4
  24. package/dist/hoi4_agent_tools/mcp/tools/reference.js +12 -12
  25. package/dist/hoi4_agent_tools/mcp/tools/technology.js +3 -3
  26. package/dist/hoi4_agent_tools/runtime.js +14 -1
  27. package/dist/hoi4_agent_tools/schemas/map-requests.js +1 -1
  28. package/dist/hoi4_agent_tools/version.js +1 -1
  29. package/docs/analysis.md +2 -2
  30. package/docs/development.md +2 -0
  31. package/docs/events.md +2 -3
  32. package/docs/examples.md +8 -23
  33. package/docs/focus.md +3 -2
  34. package/docs/gui.md +7 -4
  35. package/docs/helper-expansion.md +1 -1
  36. package/docs/jobs.md +5 -2
  37. package/docs/map.md +5 -4
  38. package/docs/mechanics.md +2 -2
  39. package/docs/probability.md +5 -2
  40. package/docs/reference.md +2 -1
  41. package/docs/setup.md +2 -4
  42. package/docs/technology.md +2 -3
  43. package/docs/tools.md +12 -13
  44. package/docs/troubleshooting.md +1 -1
  45. package/npm-shrinkwrap.json +2 -2
  46. package/package.json +2 -2
  47. package/schemas/configuration.schema.json +1 -1
  48. package/schemas/continuous-focus-palette.schema.json +1 -1
  49. package/schemas/custom-weighted-pool.schema.json +1 -1
  50. package/schemas/decision-inspect-input.schema.json +1 -1
  51. package/schemas/error-log-input.schema.json +1 -1
  52. package/schemas/event-feature-manifest.schema.json +1 -1
  53. package/schemas/focus-plan.schema.json +1 -1
  54. package/schemas/focus-planning-sidecar.schema.json +1 -1
  55. package/schemas/gui-animation-source.schema.json +1 -1
  56. package/schemas/gui-helper.schema.json +1 -1
  57. package/schemas/gui-scenario.schema.json +1 -1
  58. package/schemas/helper-expansion-request.schema.json +1 -1
  59. package/schemas/helper-expansion-summary.schema.json +1 -1
  60. package/schemas/impact-inspect-input.schema.json +1 -1
  61. package/schemas/map-operation.schema.json +1 -1
  62. package/schemas/mechanic-test-input.schema.json +1 -1
  63. package/schemas/mod-index-input.schema.json +1 -1
  64. package/schemas/operation-result.schema.json +1 -1
  65. package/schemas/package-check-input.schema.json +1 -1
  66. package/schemas/package-manifest.schema.json +1 -1
  67. package/schemas/probability-analysis-result.schema.json +1 -1
  68. package/schemas/probability-compare-input.schema.json +1 -1
  69. package/schemas/probability-evaluate-input.schema.json +1 -1
  70. package/schemas/probability-inspect-input.schema.json +1 -1
  71. package/schemas/probability-render-input.schema.json +1 -1
  72. package/schemas/probability-scenario-set.schema.json +1 -1
  73. package/schemas/probability-sequence-input.schema.json +1 -1
  74. package/schemas/probability-simulate-input.schema.json +1 -1
  75. package/schemas/probability-sweep-input.schema.json +1 -1
  76. package/schemas/reference-context-input.schema.json +1 -1
  77. package/schemas/reference-read-input.schema.json +1 -1
  78. package/schemas/reference-search-input.schema.json +1 -1
  79. package/schemas/scenario-suite.schema.json +1 -1
  80. package/schemas/scenario-test-input.schema.json +1 -1
  81. package/schemas/script-validate-input.schema.json +1 -1
  82. package/schemas/shared-scenario.schema.json +1 -1
  83. package/schemas/source-lookup-input.schema.json +1 -1
  84. package/server.json +3 -3
@@ -71,24 +71,24 @@ const artifactProducing = {
71
71
  export const guiTaskTools = [
72
72
  {
73
73
  name: 'hoi4.gui_inspect',
74
- title: 'Inspect scripted GUI',
75
- description: 'Inspect a scripted GUI window with its linked .gui, .gfx, scripted-GUI, localisation and font sources, and layout diagnostics. Example: {"windowName":"my_window"}. Returns element counts and fidelity inline; the full scene is a linked resource.',
74
+ title: 'Inspect a window',
75
+ description: 'Find the elements, assets and script behind a window, including layout problems, localisation and fonts. Example: {"windowName":"my_window"}. Returns element counts and fidelity inline; the full scene is a linked resource.',
76
76
  inputSchema: guiInspectRequestSchema,
77
77
  outputSchema: guiScanOutputSchema,
78
78
  annotations: artifactProducing,
79
79
  },
80
80
  {
81
81
  name: 'hoi4.gui_render',
82
- title: 'Render scripted GUI artifacts',
83
- description: 'Render a GUI window under a scenario at several states and resolutions, with click regions, hierarchy and a diagnostics report. Example: {"windowName":"my_window","scenario":{"id":"normal","flags":{"my_flag":true}}}. Returns a gallery of about 25 linked artifacts; undecided visibility stays marked unresolved.',
82
+ title: 'Preview a window',
83
+ description: 'Preview a window at different resolutions and states. Shows control regions, element hierarchy and layout problems; unknown visibility stays unresolved. Example: {"windowName":"my_window","scenario":{"id":"normal","flags":{"my_flag":true}}}. Images and reports are linked resources.',
84
84
  inputSchema: guiRenderRequestSchema,
85
85
  outputSchema: guiRenderOutputSchema,
86
86
  annotations: artifactProducing,
87
87
  },
88
88
  {
89
89
  name: 'hoi4.gui_rewrite',
90
- title: 'Create or clean up scripted GUI',
91
- description: 'Apply one validated GUI change as complete source, structured helpers or exact patches, plus extra text files (additionalFiles); binary art must already be in the mod. Example: {"mode":"helpers","relativePath":"interface/my_window.gui","windowName":"my_window","scenario":{"id":"normal"},"helper":{...}}. Writes atomically; returns changed files and a rollback-able transaction.',
90
+ title: 'Create or edit a window',
91
+ description: 'Create or edit a window using complete source, structured helpers or exact patches. Include related text files with additionalFiles; binary art must already be in the mod. Example: {"mode":"helpers","relativePath":"interface/my_window.gui","windowName":"my_window","scenario":{"id":"normal"},"helper":{...}}. Returns the changed files.',
92
92
  inputSchema: guiRewriteRequestSchema,
93
93
  outputSchema: guiPlanOutputSchema,
94
94
  annotations: {
@@ -4,8 +4,8 @@ import { errorResult } from '../../core/operation-result.js';
4
4
  export const jobControlTools = [
5
5
  {
6
6
  name: 'hoi4.job_inspect',
7
- title: 'Inspect persistent job',
8
- description: 'Inspect a background operation by jobId (from a native task id): status while it runs, the original tool result once it completed. Example: {"jobId":"job_<64 hex characters>"}. Returns bounded status evidence.',
7
+ title: 'Check a background task',
8
+ description: 'Check progress on a background task or retrieve its completed result. Pass jobId from the task handle. Example: {"jobId":"job_<64 hex characters>"}. Returns task status or the completed result.',
9
9
  inputSchema: jobReferenceSchema,
10
10
  annotations: {
11
11
  readOnlyHint: true,
@@ -16,8 +16,8 @@ export const jobControlTools = [
16
16
  },
17
17
  {
18
18
  name: 'hoi4.job_cancel',
19
- title: 'Cancel persistent job',
20
- description: 'Durably request cancellation of a background operation by jobId. A completed result stays completed. Example: {"jobId":"job_<64 hex characters>"}.',
19
+ title: 'Stop a background task',
20
+ description: 'Stop a background task by jobId. A result that has already completed stays available. Example: {"jobId":"job_<64 hex characters>"}.',
21
21
  inputSchema: jobReferenceSchema,
22
22
  outputSchema: jobStatusOutputSchema,
23
23
  annotations: {
@@ -127,16 +127,16 @@ const artifactProducing = {
127
127
  export const mapTaskTools = [
128
128
  {
129
129
  name: 'hoi4.map_inspect',
130
- title: 'Inspect HOI4 map',
131
- description: 'Validate the map with a searchable navigator, look up provinces, states, regions, names or coordinates (lookupOnly for speed), render a layer, tile or area, or check script references (references:true). Example: {"query":"Brandenburg","lookupOnly":true}. Returns counts and matches inline; PNG, HTML and the catalog are artifacts.',
130
+ title: 'Explore and preview the map',
131
+ description: 'Explore and preview the map. Find provinces, states and regions by name, ID or coordinates, inspect map problems and script references, or render a layer, tile or area. Use lookupOnly for a quick lookup and references:true for script references. Example: {"query":"Brandenburg","lookupOnly":true}. Returns counts and matches inline; PNG, HTML and the catalog are artifacts.',
132
132
  inputSchema: mapInspectRequestSchema,
133
133
  outputSchema: mapInspectOutputSchema,
134
134
  annotations: artifactProducing,
135
135
  },
136
136
  {
137
137
  name: 'hoi4.map_rewrite',
138
- title: 'Create or clean up map content',
139
- description: 'Create a world, or create, split, merge, move and renumber states and provinces, regenerate positions and supply, and remap script references. Example: {"operations":[{"id":"s1","kind":"create_state","provinceIds":[120,121],"displayName":"New State"}]}. All or nothing: a failed operation leaves no partial files. Returns changed IDs, semantic diff and a render.',
138
+ title: 'Build a world or edit the map',
139
+ description: 'Build a world, split or merge states, move or renumber provinces, and update script references. Regenerate building positions and supply networks. Example: {"operations":[{"id":"s1","kind":"create_state","provinceIds":[120,121],"displayName":"New State"}]}. Returns changed IDs, a summary of edits and a render.',
140
140
  inputSchema: mapRewriteRequestSchema,
141
141
  outputSchema: mapPlanOutputSchema,
142
142
  annotations: {
@@ -114,16 +114,16 @@ const readOnly = {
114
114
  export const probabilityTaskTools = [
115
115
  {
116
116
  name: 'hoi4.probability_inspect',
117
- title: 'Inspect and evaluate AI weights and MTTH',
118
- description: 'Find weighted logic (ai_will_do, ai_chance, MTTH, random_list, strategy factors) by path, ID or candidate IDs and evaluate it under declared scenarios, or none: weights, probabilities and the facts still missing. Example: {"candidatePool":["my_decision"],"scenarioSet":[{"actor":"GER","state":{"has_war":false}}]}. Ranks the strongest candidates inline.',
117
+ title: 'Explain AI choices and event timing',
118
+ description: 'Explain why the AI favours an option, decision, focus or technology. Find ai_will_do, ai_chance, MTTH, random_list or strategy factors by path, ID or candidate IDs and evaluate them under declared scenarios. Show weights, supported probabilities and missing facts. Example: {"candidatePool":["my_decision"],"scenarioSet":[{"actor":"GER","state":{"has_war":false}}]}. Ranks the strongest candidates inline.',
119
119
  inputSchema: probabilityInspectRequestSchema,
120
120
  outputSchema: inspectOutput,
121
121
  annotations: readOnly,
122
122
  },
123
123
  {
124
124
  name: 'hoi4.probability_analyze',
125
- title: 'Compare, sweep, simulate, or sequence weighted logic',
126
- description: 'Deeper weighted analysis: compare before and after source under the same scenarios, sweep input ranges for breakpoints and rank reversals, simulate uncertain inputs, run a declared pool over time, or render a retained analysis. Example: {"analysis":"sweep","source":"common/decisions/my_decisions.txt","candidatePool":["my_decision"],"scenarioSet":[{"actor":"GER","state":{"variable.pressure":10}}],"sweep":{"paths":["variable.pressure"],"steps":10}}.',
125
+ title: 'Compare AI choices and random outcomes',
126
+ description: 'Compare AI weights before and after an edit, find where a choice changes, or explore uncertain inputs and choices over time. Select compare, sweep, simulate, sequence or render with analysis. Example: {"analysis":"sweep","source":"common/decisions/my_decisions.txt","candidatePool":["my_decision"],"scenarioSet":[{"actor":"GER","state":{"variable.pressure":10}}],"sweep":{"paths":["variable.pressure"],"steps":10}}.',
127
127
  inputSchema: probabilityAnalyzeRequestSchema,
128
128
  outputSchema: analysisOutput,
129
129
  annotations: readOnly,
@@ -12,32 +12,32 @@ const readOnly = {
12
12
  export const referenceTools = [
13
13
  {
14
14
  name: 'hoi4.reference_search',
15
- title: 'Search local HOI4 references',
16
- description: 'Search the offline wiki and installed game documentation by words or script names; each hit gives its file, lines, revision and answering line. Example: {"query":"add_timed_idea"}. Returns 6 hits by default (up to 12); read one with hoi4.reference_read using its id and revision.',
15
+ title: 'Find a modding rule',
16
+ description: 'Find the right modding rule in the offline wiki and installed game docs using ordinary words or script names. Each hit includes its file, lines, revision and answering line. Example: {"query":"add_timed_idea"}. Returns 6 hits by default (up to 12); read one with hoi4.reference_read using its id and revision.',
17
17
  inputSchema: referenceSearchRequestSchema,
18
18
  outputSchema: strictOperationResultSchema(referenceSearchDataSchema),
19
19
  annotations: readOnly,
20
20
  },
21
21
  {
22
22
  name: 'hoi4.reference_read',
23
- title: 'Read cited HOI4 reference section',
24
- description: 'Read one cited documentation section: pass the id and revision of a reference_search or reference_context hit. Example: {"id":"<hit id>","revision":"<hit revision>"}. Returns at most 80 lines (40 by default) and 8,000 bytes, with a line to continue from.',
23
+ title: 'Read a modding rule',
24
+ description: 'Read a documentation section returned by reference_search or reference_context. Pass its id and revision. Example: {"id":"<hit id>","revision":"<hit revision>"}. Returns at most 80 lines (40 by default) and 8,000 bytes, with a line to continue from.',
25
25
  inputSchema: referenceReadRequestSchema,
26
26
  outputSchema: strictOperationResultSchema(referenceReadDataSchema),
27
27
  annotations: readOnly,
28
28
  },
29
29
  {
30
30
  name: 'hoi4.reference_context',
31
- title: 'Get HOI4 task references',
32
- description: 'Cited wiki and installed-documentation sections for one modding surface (event, decision, idea, focus, technology, gui, map, localisation, ai, general). Example: {"surface":"event","question":"fire an event after a delay"}. Returns up to 16 short sections; read more with hoi4.reference_read.',
31
+ title: 'Find docs for a modding task',
32
+ description: 'Find documentation for the content you are building: events, decisions, ideas, focuses, technology, GUI, maps, localisation or AI. Example: {"surface":"event","question":"fire an event after a delay"}. Returns up to 16 short sections; read more with hoi4.reference_read.',
33
33
  inputSchema: referenceContextRequestSchema,
34
34
  outputSchema: strictOperationResultSchema(referenceContextDataSchema),
35
35
  annotations: readOnly,
36
36
  },
37
37
  {
38
38
  name: 'hoi4.source_lookup',
39
- title: 'Look up HOI4 source symbol',
40
- description: 'Find where a script symbol is defined across game, DLC and mod, and where it is used; or pass path and line for the definition containing that line. Example: {"symbol":"my_scripted_effect"}. Returns up to 3 definitions with source text and 10 usages; keyPath and view=structure navigate nested blocks.',
39
+ title: 'Find definitions and usages',
40
+ description: 'Find where a script symbol is defined and used across the game, DLC and mod. Pass a symbol, or a file path and line. Example: {"symbol":"my_scripted_effect"}. Returns up to 3 definitions with source text and 10 usages; keyPath and view=structure navigate nested blocks.',
41
41
  inputSchema: sourceLookupRequestSchema,
42
42
  outputSchema: strictOperationResultSchema(sourceLookupDataSchema),
43
43
  annotations: readOnly,
@@ -45,7 +45,7 @@ export const referenceTools = [
45
45
  {
46
46
  name: 'hoi4.script_validate',
47
47
  title: 'Check HOI4 script commands and scopes',
48
- description: 'Check an effect or trigger snippet, or a whole mod file, against the installed documentation: syntax, command kinds and scopes. Unknown helpers and native argument blocks stay marked unresolved, never valid. Example: {"source":"add_political_power = 10","kind":"effect","scope":"country"} or {"path":"events/a.txt"}. Returns up to 12 findings.',
48
+ description: 'Find broken syntax, commands and scopes in an effect, trigger or mod file using the installed docs. Unknown helpers and native argument blocks stay unresolved. Example: {"source":"add_political_power = 10","kind":"effect","scope":"country"} or {"path":"events/a.txt"}. Returns up to 12 findings.',
49
49
  inputSchema: scriptValidateRequestSchema,
50
50
  outputSchema: strictOperationResultSchema(scriptValidateDataSchema),
51
51
  annotations: readOnly,
@@ -53,15 +53,15 @@ export const referenceTools = [
53
53
  {
54
54
  name: 'hoi4.error_log',
55
55
  title: 'Read the game error log',
56
- description: 'Group the game\'s logs/error.log from its last launch by category, with each entry\'s source file, line, layer and whether that file changed since; mod entries first. Example: {"scope":"mod","category":"effect"}. Returns at most 20 entries (limit 50) with fix hints and which entries are new since the previous launch.',
56
+ description: 'Find errors from the last game launch and group them by category, with source files, lines and fix hints. Show which files changed since the log and which errors appeared after a relaunch; mod entries come first. Example: {"scope":"mod","category":"effect"}. Returns at most 20 entries (limit 50) with fix hints and which entries are new since the previous launch.',
57
57
  inputSchema: errorLogRequestSchema,
58
58
  outputSchema: strictOperationResultSchema(errorLogDataSchema),
59
59
  annotations: readOnly,
60
60
  },
61
61
  {
62
62
  name: 'hoi4.mod_index',
63
- title: 'Index mod definitions and free IDs',
64
- description: 'overview: the mod descriptor, definition counts by kind, folders and event namespace ranges. next_id: the next free numbered ID for an event namespace or prefix across every layer. Example: {"mode":"next_id","kind":"event","namespace":"my_mod"}. Returns a compact summary; the first call indexes the mod, which takes seconds on a large one.',
63
+ title: 'Explore mod content and find free IDs',
64
+ description: 'Summarize the content in a mod or find a free event ID across the mod, game and dependencies. Use overview for descriptors, folders and definitions, or next_id with a namespace or prefix. Example: {"mode":"next_id","kind":"event","namespace":"my_mod"}. Returns a compact summary; the first call indexes the mod, which takes seconds on a large one.',
65
65
  inputSchema: modIndexRequestSchema,
66
66
  outputSchema: strictOperationResultSchema(modIndexDataSchema),
67
67
  annotations: readOnly,
@@ -93,15 +93,15 @@ export const technologyTaskTools = [
93
93
  {
94
94
  name: 'hoi4.tech_inspect',
95
95
  title: 'Inspect technology trees',
96
- description: 'Scan, trace, explain, list unlocks and bonus coverage, lint, assess impact or compare (mode compare) technology and doctrine graphs. Example: {"mode":"explain","technologyId":"my_tech"}. Returns counts and the main findings inline; the full report is a linked resource.',
96
+ description: 'Explain technology and doctrine paths, unlocks, bonuses and dependencies. Find layout or reference problems and compare revisions with mode compare. Example: {"mode":"explain","technologyId":"my_tech"}. Returns counts and the main findings inline; the full report is a linked resource.',
97
97
  inputSchema: inspectInputSchema,
98
98
  outputSchema: analysisOutputSchema,
99
99
  annotations: readOnlyTechnologyTool,
100
100
  },
101
101
  {
102
102
  name: 'hoi4.tech_render',
103
- title: 'Render technology trees',
104
- description: 'Render a technology folder, dependencies, doctrine, bonuses, grants, unlocks or unresolved view as JSON, SVG and PNG with real item sizes and year guides. Example: {"view":"folder","folderId":"my_folder"}. Images are linked artifacts.',
103
+ title: 'Preview technology trees',
104
+ description: 'Preview technology folders and doctrines with their icons, item sizes and year guides. Show dependencies, bonuses, grants, unlocks or unresolved references as JSON, SVG and PNG. Example: {"view":"folder","folderId":"my_folder"}. Images are linked artifacts.',
105
105
  inputSchema: renderInputSchema,
106
106
  outputSchema: renderOutputSchema,
107
107
  annotations: readOnlyTechnologyTool,
@@ -1,11 +1,12 @@
1
1
  import { lstat, readdir, stat } from 'node:fs/promises';
2
2
  import path from 'node:path';
3
- import { homedir } from 'node:os';
3
+ import { homedir, tmpdir } from 'node:os';
4
4
  import { loadConfiguration, serverConfigurationSchema, } from './core/configuration.js';
5
5
  import { CoreEngine } from './core/engine.js';
6
6
  import { ServiceError } from './core/result.js';
7
7
  import { WorkspaceResolver } from './core/workspace.js';
8
8
  import { CONFIG_VERSION } from './version.js';
9
+ import { sweepTemporaryDirectories } from './core/temporary-directories.js';
9
10
  export function defaultConfigurationPath() {
10
11
  const configRoot = process.env.APPDATA ?? process.env.XDG_CONFIG_HOME ?? path.join(homedir(), '.config');
11
12
  return path.join(configRoot, 'hoi4-agent-tools', 'config.json');
@@ -236,6 +237,18 @@ export async function createEngine(configPath = configurationPath()) {
236
237
  configuration = await automaticConfiguration();
237
238
  }
238
239
  const resolver = await WorkspaceResolver.create(configuration);
240
+ await sweepTemporaryDirectories(tmpdir(), {
241
+ protectedRoots: [
242
+ ...resolver
243
+ .list()
244
+ .flatMap((workspace) => [
245
+ ...workspace.roots.map((root) => root.path),
246
+ workspace.artifactRoot,
247
+ workspace.cacheRoot,
248
+ ]),
249
+ ...(resolver.serverState() === undefined ? [] : [resolver.serverState().root]),
250
+ ],
251
+ }).catch(() => undefined);
239
252
  const engine = new CoreEngine(resolver);
240
253
  await engine.initialize();
241
254
  return engine;
@@ -99,7 +99,7 @@ export const mapInspectRequestSchema = z
99
99
  .describe('Also check events, focuses, decisions, history and AI areas for states, provinces and regions the map lacks, and state tags without a country.'),
100
100
  layer: mapLayerSchema
101
101
  .optional()
102
- .describe('Render this base layer instead of validating; combine with overlays, tile or area.'),
102
+ .describe('Render this base layer; combine with overlays, tile or area.'),
103
103
  overlays: z.array(mapOverlaySchema).max(12).optional(),
104
104
  scale: z.number().int().min(1).max(16).optional(),
105
105
  tile: mapTileSchema.optional().describe('Render one top-left bitmap area.'),
@@ -1,6 +1,6 @@
1
1
  import { LATEST_PROTOCOL_VERSION } from '@modelcontextprotocol/sdk/types.js';
2
2
  export const PACKAGE_NAME = 'hoi4-agent-tools';
3
- export const PACKAGE_VERSION = '4.0.0';
3
+ export const PACKAGE_VERSION = '4.0.3';
4
4
  export const MCP_PROTOCOL_VERSION = LATEST_PROTOCOL_VERSION;
5
5
  export const CONFIG_VERSION = 1;
6
6
  export const TRANSACTION_VERSION = 1;
package/docs/analysis.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Cross-system impact and decisions
2
2
 
3
- `hoi4.impact_inspect` and `hoi4.decision_inspect` analyze authorized HOI4 source without changing it or running the game.
4
- Both tools return a compact result and a linked JSON report containing source locations, hashes, unresolved cases, and the full analysis.
3
+ Find out why a decision is hidden or unavailable, and see what a script change affects elsewhere in the mod.
4
+ `hoi4.impact_inspect` and `hoi4.decision_inspect` return a summary and a linked JSON report with source locations, hashes and unresolved cases.
5
5
  They support ordinary calls and persistent MCP tasks through stdio and HTTP.
6
6
 
7
7
  ## Cross-system impact
@@ -19,6 +19,8 @@ npm run inspector
19
19
 
20
20
  Keep changes focused and include tests for behavior changes. CI fixtures must be synthetic and project-owned; never commit installed-game or third-party-mod content. Public tool or schema changes require compatibility review and a versioned release.
21
21
 
22
+ Vitest tracks temporary fixtures created with `mkdtemp` and removes them after each test or suite teardown, with process-exit cleanup as a fallback. Fixture writes and truncations reserve a 256 MiB aggregate disk budget. Test oversized inputs with a small injected limit or mocked metadata; do not allocate gigabyte fixtures. Startup recovery preserves live owners, locks and dated benchmark evidence; see [temporary fixture ownership](adr/0048-temporary-fixture-lifetimes.md).
23
+
22
24
  The event-chain acceptance fixture contains more than 300 project-owned event definitions and exercises routes, options, timing, state flow, scope changes, unresolved dynamic calls, rendering, and comparison.
23
25
 
24
26
  The technology acceptance fixture contains 1,040 project-owned technologies across 13 folders and exercises classic and current doctrines, prerequisites, exclusive branches, multiple placements, unlocks, bonuses, grants, assets, unresolved references, rendering, and comparison.
package/docs/events.md CHANGED
@@ -1,8 +1,7 @@
1
1
  # Event chains
2
2
 
3
- The Event Chain Viewer analyzes event definitions and call sites across the active mod, configured dependencies, and vanilla sources. It is read-only: it does not rewrite event files or simulate the game.
4
-
5
- Use the three event tools directly from the target mod.
3
+ Follow event chains, see the choices they offer and find broken calls.
4
+ The event tools analyze the mod, its dependencies and vanilla sources. The agent uses the results with its file editor to create or fix events.
6
5
 
7
6
  ## Inspect
8
7
 
package/docs/examples.md CHANGED
@@ -1,13 +1,10 @@
1
1
  # Examples
2
2
 
3
- Start with a task you would normally give your coding agent.
4
- The agent chooses the MCP tools and opens the resulting images or source references.
5
- The renders below use real mod and installed HOI4 files; use names from your own mod when trying the prompts.
3
+ Describe what you want to make or fix and the agent chooses the tools.
4
+ The previews below come from real mod and installed HOI4 files.
6
5
 
7
6
  ## Find a rule without reading a whole wiki
8
7
 
9
- > Find the installed documentation for `save_event_target_as`, read the relevant section, and show a vanilla usage. Keep the file and line references.
10
-
11
8
  The reference tools find the section, read a small excerpt, and retain its source revision so the agent can return to it later.
12
9
  In the [measured reference example](research/reference-benchmark.md), the search found the installed effect documentation first and a 12-line read supplied the command and supported scopes.
13
10
  No wiki download or game launch was needed.
@@ -16,54 +13,42 @@ Use [Local references](reference.md) to configure an offline wiki snapshot or na
16
13
 
17
14
  ## Review a large tree
18
15
 
19
- > Render the mod's largest branching focus tree. Check its branch connections, alternative prerequisites, missing references and crowded areas before suggesting edits.
20
-
21
16
  [![Branching focus tree preview](images/comparisons/utopia-mcp.png)](images/comparisons/utopia-mcp.png)
22
17
 
23
18
  Open the image at full size for the complete layout.
24
- This example contains 124 focuses in the recorded source version.
25
19
  The [focus guide](focus.md) covers inspecting, rendering and reorganizing trees.
26
20
 
27
21
  ## Preview technology layouts and artwork
28
22
 
29
- > Render the infantry technology folder using this mod and its installed game assets. Check card sizes, icons, prerequisite links and missing placements.
30
-
31
23
  [![Infantry technology folder](images/comparisons/infantry-mcp.png)](images/comparisons/infantry-mcp.png)
32
24
 
33
25
  The preview follows the loaded technology and GUI definitions, including wide equipment cards.
34
26
  The [technology comparisons](https://github.com/klimPaskov/hoi4-agent-tools/blob/main/docs/visual-comparisons.md#technology-folders) also show a mod folder with wide equipment cards rendered from a matching recorded source revision.
35
27
  See the [technology guide](technology.md) for grants, bonuses and doctrine paths.
36
28
 
37
- ## Inspect an interface before editing it
38
-
39
- > Find the Video options window in the installed interface files. Render it with labelled control regions, then check its text, spacing and clipping.
29
+ ## Preview a window
40
30
 
41
31
  | Supplied in-game capture | MCP source preview |
42
32
  | ------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
43
33
  | ![Video options in game](images/comparisons/gui/options-video-ingame.png) | ![Video options preview](images/comparisons/gui/options-video-mcp.png) |
44
34
 
45
- For a mod window, ask for the same view at 100% and 125% UI scale and supply the state values needed by its controls.
35
+ The agent can preview mod windows at different UI scales and work out which state values their controls need.
46
36
  Unknown state values must stay unresolved; a visible button alone does not establish that it is enabled in the game.
47
37
  The [interface gallery](https://github.com/klimPaskov/hoi4-agent-tools/blob/main/docs/gui-comparisons.md) includes a vanilla priority panel, a mod settings window, an event log, a status panel, and the decision and occupation views.
48
38
 
49
- ## Locate map data and plan an edit
50
-
51
- > Find Brandenburg by name, show it on the map, and inspect its provinces, neighbours and railway connections. Show the affected files before changing anything.
39
+ ## Reshape a map
52
40
 
53
41
  [![Map rendered from installed source](images/comparisons/source/map-mcp.png)](images/comparisons/source/map-mcp.png)
54
42
 
55
- After reviewing the selection, you can ask for a specific change such as moving named provinces into a state or updating a railway path.
56
- The map tools check connected records and preserve dated state history when the operation can be represented safely.
43
+ The agent finds the state, splits its provinces and updates connected map records and script references.
44
+ It can also generate a whole new world.
57
45
  See [Maps](map.md) for supported edits.
58
46
 
59
47
  ## Trace an event or compare AI weights
60
48
 
61
- > Trace this event's options and follow-up events. Point out unresolved calls and link each route to its source.
62
-
63
49
  [![Mod event options](images/comparisons/source/event-chain-mcp.png)](images/comparisons/source/event-chain-mcp.png)
64
50
 
65
- > Compare this decision's `ai_will_do` score before and after my change in peace and war. List missing conditions separately from known results.
66
-
51
+ The AI tools show why a route is favoured or ignored.
67
52
  Use [Events](events.md) for route graphs and [AI analysis](probability.md) for supported weights, chances and timing models.
68
53
  A decision score is not automatically a percentage chance of an AI click.
69
54
 
package/docs/focus.md CHANGED
@@ -1,10 +1,11 @@
1
1
  # Focus trees
2
2
 
3
- Use `hoi4.focus_inspect`, `hoi4.focus_render`, and `hoi4.focus_rewrite` for national focus trees and continuous focus palettes.
3
+ Build focus trees, arrange branches and preview the result.
4
+ Use `hoi4.focus_inspect`, `hoi4.focus_render` and `hoi4.focus_rewrite` for national focus trees and continuous-focus palettes.
4
5
 
5
6
  ## Create a tree
6
7
 
7
- A complete plan should include:
8
+ The agent assembles the tree from your request. For a direct API call, the `plan` argument should include:
8
9
 
9
10
  - tree ID and country assignment;
10
11
  - branch and lane groups;
package/docs/gui.md CHANGED
@@ -1,11 +1,10 @@
1
1
  # Scripted GUIs
2
2
 
3
- Use `hoi4.gui_inspect`, `hoi4.gui_render`, and `hoi4.gui_rewrite` for `.gui`, `.gfx`, `common/scripted_guis`, localisation, sprites, fonts, and linked decision entry points.
3
+ Build and edit windows, preview their states and find layout problems.
4
+ Use `hoi4.gui_inspect`, `hoi4.gui_render` and `hoi4.gui_rewrite` for `.gui`, `.gfx`, `common/scripted_guis`, localisation, sprites, fonts and linked decisions.
4
5
 
5
6
  ## Start with a preview
6
7
 
7
- > Render this window at 100% and 125% UI scale. Show its control regions and list the state inputs needed to establish visibility and availability.
8
-
9
8
  The [interface examples](https://github.com/klimPaskov/hoi4-agent-tools/blob/main/docs/gui-comparisons.md) show real vanilla and mod windows.
10
9
  Cyan click regions have confirmed availability under the supplied scenario.
11
10
  Dashed amber regions are potential controls with unresolved visibility or enabling conditions; they do not count as confirmed branch coverage.
@@ -27,7 +26,7 @@ The preview does not establish native automatic positioning, frame composition,
27
26
 
28
27
  ## Create a GUI
29
28
 
30
- `hoi4.gui_rewrite` can work from supported source, targeted patches, or structured helpers. Source and helper rewrites may include one bounded text package: the main `.gui` plus additional interface `.gui`/`.gfx`, configured GFX `.gfx`, `common/scripted_guis/*.txt`, and localisation `.yml` files. The package is path-checked, parsed, linked, rendered, validated, and applied together in one rewrite. Existing text encodings are retained, while localisation is always written as UTF-8 with BOM.
29
+ `hoi4.gui_rewrite` can work from supported source, targeted patches, or structured helpers. Source and helper rewrites may include one bounded text package: the main `.gui` plus additional interface `.gui`/`.gfx`, configured GFX `.gfx`, `common/scripted_guis/*.txt`, and localisation `.yml` files. The related files are written together. Existing text encodings are retained, while localisation is always written as UTF-8 with BOM.
31
30
 
32
31
  A package may contain at most 32 text files and 16 MiB of encoded source in total. Paths are compared portably, so aliases that differ only by letter case are rejected.
33
32
 
@@ -103,6 +102,10 @@ For native country-flag controls, bind `element_name.countryTag` and `element_na
103
102
  Only valid bounded tag tokens enter asset discovery; an invalid tag is reported, not converted into a different country's identifier or a filesystem path.
104
103
  An unrelated global country value does not turn every native icon into a flag.
105
104
 
105
+ Some vanilla windows are not scripted: the game itself shows one branch of the window and picks an icon frame from the player's country. `countrypoliticsview` is modelled this way. Its `no_faction`, `original_in_faction` (faction leader), `in_faction` (faction member) and `power_balance_button` branches are shown only when they apply, and `pol_faction_icon` shows the frame of the ruling ideology (fascism, communism, democratic or neutrality) instead of its static `frame = 1`.
106
+ The facts come from `scenario.country`: `tag`, `ideology`, `faction` (`none`, `member` or `leader`) and `balanceOfPower` (boolean). A fact the scenario does not set is read from `history/countries` at the scenario `date` (default 1936.1.1): `set_politics`, `create_faction`, `add_to_faction` in other countries' histories, and `set_power_balance`, with dated blocks later than the scenario date ignored and DLC-conditioned blocks treated as owned. With no country at all, the window shows a country in no faction without a balance of power and reports the approximation. Explicit `visibility`, `values` (`name.visible`, `name.frame`) and `selectedFrames` always win. Every decision is listed under `modelled` as `native_window_state`.
107
+ Source visibility accepts `visible`, `show`, `hide` and `hidden`. Scenario visibility values may be booleans, `yes`/`no`, `true`/`false`, `visible`/`hidden`, or 1/0.
108
+
106
109
  `hoi4.gui_inspect` and `hoi4.gui_render` generate a seeded exploratory preview by default. The generator follows the complete `parent_scripted_gui` surface, discovers numeric and text tokens, fills meters within their declared ranges, and populates dynamic lists with coherent rows. Scripted-localisation text and sprite branches use the same structured condition evaluator as probability analysis, including compound conditions, inclusive comparisons, constants, declared scopes, and scripted triggers. An unknown earlier condition leaves the token unresolved instead of guessing a branch. The scenario's `conditionResults` records checked choices and missing inputs. Explicit values remain authoritative; generated inputs are not verified campaign state. Normal controls and animation frames remain stable unless variation is requested. Every explicit `relatedScenarios` entry is rendered beside the generated view.
107
110
 
108
111
  Declare scoped facts with `scopes`, for example `"scopes": { "FROM": { "id": "target", "actor": "FRA", "state": { "support": 10 } } }`. Existing flat values such as `FROM.support` remain usable. Seeded pane and active/idle selection is exploratory layout sampling, not proof that every visibility branch is reachable.
@@ -1,7 +1,7 @@
1
1
  # Bounded helper expansion
2
2
 
3
3
  `hoi4.event_inspect` and `hoi4.tech_inspect` accept `mode: "helper_expansion"`.
4
- This is a read-only stream of source-linked helper paths, not a source rewrite or runtime simulation.
4
+ Follow helper calls back to their source and see where analysis could not resolve them.
5
5
  It avoids materializing the whole helper closure before returning its first page.
6
6
 
7
7
  Start either tool with:
package/docs/jobs.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # Persistent jobs and MCP tasks
2
2
 
3
- Long-running domain operations support optional MCP tasks while preserving the ordinary tool-call contract.
3
+ Let a large preview or analysis run in the background, check its progress or stop it.
4
+ Long-running operations support optional MCP tasks and ordinary tool calls.
4
5
  Clients that negotiate task support can request a task, disconnect, reconnect with the same authorized identity, inspect or cancel it, and retrieve the original tool result after completion.
5
6
  Clients that do not request a task receive the ordinary synchronous tool result.
6
7
 
@@ -62,7 +63,9 @@ A read-only job still running `jobCancelGraceSeconds` (1–600, default 10) afte
62
63
  A read-only job still running `jobDeadlineSeconds` (1–86,400, default 1,800) after it was dispatched is stopped and fails with `JOB_DEADLINE_EXCEEDED`; narrow its selector or limits, or raise the setting in the server configuration.
63
64
  Rewrite jobs are never stopped this way, because their transaction journal owns write recovery; they keep cooperative cancellation and reconciliation.
64
65
  Supervision belongs to the server process that dispatched the worker. A read-only worker whose dispatching server has exited enforces the same deadline itself and then exits; a rewrite worker keeps running until it finishes.
65
- `jobWorkerMaxHeapMiB` (256–65,536) sets a V8 heap ceiling for each worker; without it, workers use Node's default. A worker that runs out of memory ends a job with `JOB_WORKER_EXIT`; retry the call, which starts a fresh worker, or raise the ceiling.
66
+ `jobWorkerMaxHeapMiB` (256–65,536) sets a V8 heap ceiling for each worker; without it, a worker gets a quarter of physical memory, between 2,048 and 8,192 MiB.
67
+ A worker that stops without publishing a result ends the job with `JOB_WORKER_EXIT`, and the message gives the cause the server observed: a V8 heap limit (with its size), a native out-of-memory, a native crash, termination from outside the server, a stop by the server's own deadline, or an uncaught job error with its error code, together with the exit code or signal. Only a V8 heap limit or a native out-of-memory is a memory failure; raise `jobWorkerMaxHeapMiB` or narrow the request for those, and retry otherwise.
68
+ The standard error of the newest ten workers that ended unexpectedly is kept in `job-workers/logs` under the server state root.
66
69
  At most `maxSharedTools` (1–128, default 4) workers and expensive calls run at once across every server process that shares a `serverStateRoot`; further work waits for capacity.
67
70
 
68
71
  Read-only jobs stage a source-revision-bound result checkpoint before terminal publication.
package/docs/map.md CHANGED
@@ -1,10 +1,11 @@
1
1
  # Maps
2
2
 
3
- Use `hoi4.map_inspect` and `hoi4.map_rewrite` for provinces, states, strategic regions, adjacency, supply nodes, railways, positions, ownership, cores, claims, resources, buildings, and localisation.
3
+ Generate a new world, split states and reshape provinces. Preview the map and update the scripts that refer to it.
4
+ Use `hoi4.map_inspect` and `hoi4.map_rewrite` for provinces, states, regions, supply, railways, positions, ownership, resources, buildings and localisation.
4
5
 
5
6
  ## Inspect and navigate the complete map
6
7
 
7
- `hoi4.map_inspect` validates the map and returns a full-map PNG plus a searchable, clickable HTML navigator by default. The navigator supports pan, zoom, fit-to-map, search by numeric ID, localisation key, or localised name, and exact click lookup for province, state, and strategic-region IDs. Hovering reports both top-left bitmap coordinates and bottom-left HOI4 map coordinates.
8
+ `hoi4.map_inspect` finds map problems and returns a full-map PNG plus a searchable, clickable HTML navigator by default. The navigator supports pan, zoom, fit-to-map, search by numeric ID, localisation key, or localised name, and exact click lookup for province, state, and strategic-region IDs. Hovering reports both top-left bitmap coordinates and bottom-left HOI4 map coordinates.
8
9
 
9
10
  The linked JSON catalog contains every active province definition, state, and strategic region with resolved names, alternate localisation values, source paths and lines, raster bounds and centers, memberships, neighbors, victory points, resources, buildings, ports, supply nodes, railways, normal and special adjacencies, building positions, unit positions, weather positions, and entity locators. Large catalog and render data remain in MCP resources instead of filling the agent prompt.
10
11
 
@@ -231,11 +232,11 @@ Width and height are multiples of 256 with at most 13,238,272 pixels. Land comes
231
232
 
232
233
  The operation writes `provinces.bmp`, `definition.csv`, `default.map`, `continent.txt`, `heightmap.bmp`, `terrain.bmp`, `rivers.bmp` (rivers run downhill to the coast), `trees.bmp`, `cities.bmp`, `world_normal.bmp`, the land and water colour maps, `adjacencies.csv`, strategic regions (`landProvincesPerRegion`, `seaProvincesPerRegion`) with weather by latitude, states (`provincesPerState`) with population, category, buildings, resources, victory points and ports, country tags, country files, history and three-band flags, a bookmark, localisation, and every position, supply node and railway. Countries grow from spread-out capitals in proportion to `share`; each state lies within one country and one strategic region.
233
234
 
234
- With `replaceBaseGame` (default `true`) it adds `replace_path` lines for `history/states`, `history/countries`, `history/units`, `map/strategicregions`, `map/supplyareas` and `common/bookmarks` to `descriptor.mod`, and its info diagnostic reminds you that the launcher's `.mod` file beside the mod folder needs the same lines. Base-game events, focuses and decisions still name base-game states; `map_inspect` with `references: true` lists them for replacement or remapping. The same seed always gives the same world, and the result is validated like any other rewrite; afterwards refine it with the other operations.
235
+ With `replaceBaseGame` (default `true`) it adds `replace_path` lines for `history/states`, `history/countries`, `history/units`, `map/strategicregions`, `map/supplyareas` and `common/bookmarks` to `descriptor.mod`, and its info diagnostic reminds you that the launcher's `.mod` file beside the mod folder needs the same lines. Base-game events, focuses and decisions still name base-game states; `map_inspect` with `references: true` lists them for replacement or remapping. The same seed always gives the same world. Refine it with the other operations.
235
236
 
236
237
  ## Worked example: build a world, then reshape it
237
238
 
238
- 1. Create the world. The result is validated like any other rewrite, and the same seed always gives the same world.
239
+ 1. Create the world. The same seed always gives the same world.
239
240
 
240
241
  ```json
241
242
  {
package/docs/mechanics.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Mechanic tests, package checks, and scenario suites
2
2
 
3
- `hoi4.mechanic_test`, `hoi4.package_check`, and `hoi4.scenario_test` read authorized HOI4 source and return linked, revision-bound evidence.
4
- They do not launch the game or change source files.
3
+ Test scripted effects, find missing pieces of a feature and run repeatable scenarios.
4
+ `hoi4.mechanic_test`, `hoi4.package_check` and `hoi4.scenario_test` evaluate mod source and return reports tied to that source revision.
5
5
  Supply `expectedRevision` when continuing analysis against a reviewed scan.
6
6
 
7
7
  ## Test an effect
@@ -1,6 +1,7 @@
1
1
  # AI and MTTH scenario analysis
2
2
 
3
- The probability tools explain weighted HOI4 logic under explicit world-state scenarios. They inspect real mod source or proposed in-memory source, show which conditions and modifiers apply, calculate only probabilities supported by the selected HOI4 surface, and keep every unresolved input visible.
3
+ Find out why the AI favours one choice and ignores another. Compare weights, conditions and timing to help your agent balance events, decisions, focuses and research.
4
+ The tools evaluate existing or proposed source under declared game conditions and list any missing facts.
4
5
 
5
6
  Use them for event timing and option weights, decision and mission scores, focus selection, technology and doctrine selection, direct random chances, `random_list`, supported AI strategy factors, and declared custom weighted pools.
6
7
 
@@ -9,7 +10,9 @@ Use them for event timing and option weights, decision and mission scores, focus
9
10
  | `hoi4.probability_inspect` | Find weighted logic by file, identifier or candidate IDs and evaluate it: each candidate's weight and probability per scenario, the strongest first, and the facts still missing. |
10
11
  | `hoi4.probability_analyze` | Deeper analysis selected by `analysis`: `compare` a proposed or frozen source, `sweep` declared ranges, `simulate` uncertain inputs, `sequence` a declared pool over time, `render` a retained analysis. |
11
12
 
12
- Both tools are read-only. Proposed source is parsed in memory and never written. When an installed game root is configured, evaluation fails closed unless `launcher-settings.json` identifies the supported HOI4 build and checksum. Results otherwise state that they target the adapter version without claiming local-game verification.
13
+ ## Game version
14
+
15
+ When `gameRoot` is configured, `launcher-settings.json` must identify the supported HOI4 build and checksum for evaluation to run. Without a game root, results identify the adapter version. Proposed source is evaluated in memory.
13
16
 
14
17
  ## One call for current weights
15
18
 
package/docs/reference.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # Local references and source lookup
2
2
 
3
- The reference tools read only local, authorized sources. They do not fetch the Paradox Wiki or start Hearts of Iron IV. The installed game's documentation has the highest authority for current syntax; the offline wiki supplies broader modding guidance. A result identifies its source, path, exact lines, and SHA-256 revision so an agent can inspect only the relevant section.
3
+ Find the right modding rule and see how vanilla uses it. The tools search local game documentation, an offline wiki and your mod source.
4
+ The installed game docs define current syntax; the wiki supplies broader guidance. Each result includes its file, lines and source revision.
4
5
 
5
6
  The server discovers these directories for a workspace:
6
7
 
package/docs/setup.md CHANGED
@@ -44,11 +44,9 @@ After `--init` writes a configuration file, every folder under its mod roots is
44
44
  The [configuration reference](configuration.md#how-the-server-picks-your-mod) gives the exact rules, the default file location, every key and the environment variables.
45
45
  Indexes are kept in the server's state folder and generated images in workspace storage, both in your user data directory by default.
46
46
 
47
- ## 3. Try a small task
47
+ ## 3. Start working
48
48
 
49
- > Find the focus trees in this mod and render one of them.
50
-
51
- > Find the installed documentation for `save_event_target_as` and read only the relevant section.
49
+ Tell your agent what you want to build or fix in the mod.
52
50
 
53
51
  Continue with the [examples guide](examples.md).
54
52
  Without a configuration file, the folder must look like a mod: it needs `descriptor.mod` or standard HOI4 content folders.
@@ -1,8 +1,7 @@
1
1
  # Technology trees
2
2
 
3
- The Technology Tree Viewer reconstructs classic technologies, legacy doctrine technologies, and current doctrine definitions across the active mod, configured dependencies, and vanilla sources. It links prerequisites, folder placements, exclusive choices, categories, tags, unlocks, bonuses, grants, localisation, icons, and AI metadata without launching the game.
4
-
5
- Use the three technology tools directly from the target mod.
3
+ Preview technology trees and doctrines. Follow research paths, unlocks and bonuses, and find missing links or misplaced items.
4
+ The tools reconstruct classic technologies and legacy and current doctrines from the mod, its dependencies and vanilla sources.
6
5
 
7
6
  ## Inspect
8
7