hoi4-agent-tools 4.6.4 → 4.6.5

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 (53) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/hoi4_agent_tools/core/artifacts.js +9 -2
  3. package/dist/hoi4_agent_tools/core/changed-summary.js +41 -0
  4. package/dist/hoi4_agent_tools/core/job-worker-host.js +5 -1
  5. package/dist/hoi4_agent_tools/map/references.js +26 -1
  6. package/dist/hoi4_agent_tools/map/render.js +29 -3
  7. package/dist/hoi4_agent_tools/map/service.js +3 -0
  8. package/dist/hoi4_agent_tools/map/tool-operations.js +5 -0
  9. package/dist/hoi4_agent_tools/version.js +1 -1
  10. package/docs/map.md +5 -2
  11. package/docs/troubleshooting.md +12 -11
  12. package/npm-shrinkwrap.json +2 -2
  13. package/package.json +1 -1
  14. package/schemas/configuration.schema.json +1 -1
  15. package/schemas/continuous-focus-palette.schema.json +1 -1
  16. package/schemas/custom-weighted-pool.schema.json +1 -1
  17. package/schemas/decision-inspect-input.schema.json +1 -1
  18. package/schemas/error-log-input.schema.json +1 -1
  19. package/schemas/event-feature-manifest.schema.json +1 -1
  20. package/schemas/focus-plan.schema.json +1 -1
  21. package/schemas/focus-planning-sidecar.schema.json +1 -1
  22. package/schemas/geography-model.schema.json +1 -1
  23. package/schemas/gui-animation-source.schema.json +1 -1
  24. package/schemas/gui-helper.schema.json +1 -1
  25. package/schemas/gui-scenario.schema.json +1 -1
  26. package/schemas/helper-expansion-request.schema.json +1 -1
  27. package/schemas/helper-expansion-summary.schema.json +1 -1
  28. package/schemas/impact-inspect-input.schema.json +1 -1
  29. package/schemas/map-operation.schema.json +1 -1
  30. package/schemas/mechanic-test-input.schema.json +1 -1
  31. package/schemas/mod-index-input.schema.json +1 -1
  32. package/schemas/operation-result.schema.json +1 -1
  33. package/schemas/package-check-input.schema.json +1 -1
  34. package/schemas/package-manifest.schema.json +1 -1
  35. package/schemas/probability-analysis-result.schema.json +1 -1
  36. package/schemas/probability-compare-input.schema.json +1 -1
  37. package/schemas/probability-evaluate-input.schema.json +1 -1
  38. package/schemas/probability-inspect-input.schema.json +1 -1
  39. package/schemas/probability-render-input.schema.json +1 -1
  40. package/schemas/probability-scenario-set.schema.json +1 -1
  41. package/schemas/probability-sequence-input.schema.json +1 -1
  42. package/schemas/probability-simulate-input.schema.json +1 -1
  43. package/schemas/probability-sweep-input.schema.json +1 -1
  44. package/schemas/reference-context-input.schema.json +1 -1
  45. package/schemas/reference-read-input.schema.json +1 -1
  46. package/schemas/reference-search-input.schema.json +1 -1
  47. package/schemas/reference-sheets.schema.json +1 -1
  48. package/schemas/scenario-suite.schema.json +1 -1
  49. package/schemas/scenario-test-input.schema.json +1 -1
  50. package/schemas/script-validate-input.schema.json +1 -1
  51. package/schemas/shared-scenario.schema.json +1 -1
  52. package/schemas/source-lookup-input.schema.json +1 -1
  53. package/server.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.6.5 - 2026-11-01
4
+
5
+ - Say how much a map rewrite changed when its file list is cut. The inline result lists at most a bounded number of changed files, so a world write of thousands of files could read as if little or nothing changed. Every applied map rewrite now adds `data.changedSummary`: the total of changed files, how many were created, removed and modified, and the same counts for the 40 folders with the most changes (two levels deep, largest first, `omittedFolders` for the rest). The full list stays in the transaction artifacts.
6
+ - Write a world over an existing world of the same size. The review renders stored before the write listed every building, unit and weather position twice (before and proposed, JSON and HTML, about 90 MB each for a 5120 x 2560 world), and a replaced world changes every position, so the batch passed the fixed 512 MiB in-memory ceiling (`ARTIFACT_LOGICAL_BATCH_LIMIT`) or ran the worker out of memory. The before and proposed renders now count positions instead of listing them (the pictures still draw them), and `map-diff.json` lists at most 2,000 changed positions per kind with the full count in `positionChanges`. On the measured ZIN world the position records were 64 MB of each 88 MB render catalog. `ARTIFACT_LOGICAL_BATCH_LIMIT` and `ARTIFACT_STORAGE_LIMIT` now name the size reached, the limit and the three largest artifacts, and `JOB_WORKER_EXIT` adds the job's last progress message.
7
+ - Stop two false map reference findings from `hoi4.map_inspect` with `references: true`. `state = 0`, as in `NOT = { state = 0 }`, tests for a valid state and is no longer an error for a missing state 0 (8 errors on Chaos Redux). A province id in a `prioritize` list, which the effects documentation gives state ids only (vanilla `prioritize = { 521 7564 }`, 26 entries), is now its own finding `MAP_SCRIPT_PRIORITIZE_PROVINCE` (a warning in the mod's files, information in game files) and no longer counts as a missing state. On Chaos Redux the missing references fall from 36 to the 2 that are real.
8
+
3
9
  ## 4.6.4 - 2026-11-01
4
10
 
5
11
  - Write a large world without hitting the scan limit. The check after a map write read every changed file again, bitmaps and textures included, with the base game's files of the same names: 270 MB for a 5120 x 2560 world, past the default `scanMaxBytes` of 256 MiB, so the write was restored after seven minutes with `SCAN_BYTE_LIMIT`. It now reads the changed text files only. See the amendment to ADR 0047.
@@ -268,9 +268,16 @@ async function preflightArtifactBatch(writes, limits, signal) {
268
268
  const preparationCeiling = Math.min(maxBytes, artifactLogicalBatchMaxBytes);
269
269
  if (totalBytes > preparationCeiling) {
270
270
  const fixedCeilingApplies = artifactLogicalBatchMaxBytes <= maxBytes;
271
- throw new ServiceError(fixedCeilingApplies ? 'ARTIFACT_LOGICAL_BATCH_LIMIT' : 'ARTIFACT_STORAGE_LIMIT', fixedCeilingApplies
271
+ const largest = writes
272
+ .map(({ name }, index) => ({ name, size: contentLengths[index] }))
273
+ .sort((left, right) => right.size - left.size || compareCodeUnits(left.name, right.name))
274
+ .slice(0, 3);
275
+ const mib = (bytes) => `${(bytes / 1_048_576).toFixed(1)} MiB`;
276
+ throw new ServiceError(fixedCeilingApplies ? 'ARTIFACT_LOGICAL_BATCH_LIMIT' : 'ARTIFACT_STORAGE_LIMIT', `${fixedCeilingApplies
272
277
  ? 'Logical artifact batch exceeds the fixed in-memory preparation ceiling'
273
- : 'Logical artifact batch exceeds the configured aggregate artifact-byte limit', { size: totalBytes, maximumBytes: preparationCeiling });
278
+ : 'Logical artifact batch exceeds the configured aggregate artifact-byte limit'} (${mib(totalBytes)} in ${writes.length} artifacts, limit ${mib(preparationCeiling)}; largest: ${largest
279
+ .map(({ name, size }) => `${name} ${mib(size)}`)
280
+ .join(', ')})`, { size: totalBytes, maximumBytes: preparationCeiling, artifacts: writes.length, largest });
274
281
  }
275
282
  if (projectedEntries > maxEntries) {
276
283
  throw new ServiceError('ARTIFACT_STORAGE_LIMIT', 'Artifact batch exceeds the configured artifact-entry limit', { projectedEntries, maximumEntries: maxEntries });
@@ -0,0 +1,41 @@
1
+ /** The folder a path is counted in: its directory, at most two levels deep (`.` for the root). */
2
+ function folderOf(relativePath) {
3
+ const parts = relativePath.replaceAll('\\', '/').split('/');
4
+ parts.pop();
5
+ return parts.length === 0 ? '.' : parts.slice(0, 2).join('/');
6
+ }
7
+ /**
8
+ * A bounded count of what a rewrite changed, so a response whose file list is cut still says how
9
+ * much changed: created, removed and modified files in total and per folder. Deterministic.
10
+ */
11
+ export function summarizeChangedFiles(files, limit = 40) {
12
+ const byFolder = new Map();
13
+ let created = 0;
14
+ let removed = 0;
15
+ let modified = 0;
16
+ for (const file of files) {
17
+ const kind = file.beforeSha256 === null ? 'created' : file.afterSha256 === null ? 'removed' : 'modified';
18
+ if (kind === 'created')
19
+ created += 1;
20
+ else if (kind === 'removed')
21
+ removed += 1;
22
+ else
23
+ modified += 1;
24
+ const folder = folderOf(file.relativePath);
25
+ const entry = byFolder.get(folder) ?? { folder, created: 0, removed: 0, modified: 0 };
26
+ entry[kind] += 1;
27
+ byFolder.set(folder, entry);
28
+ }
29
+ const ranked = [...byFolder.values()].sort((left, right) => right.created +
30
+ right.removed +
31
+ right.modified -
32
+ (left.created + left.removed + left.modified) || (left.folder < right.folder ? -1 : 1));
33
+ return {
34
+ total: files.length,
35
+ created,
36
+ removed,
37
+ modified,
38
+ folders: ranked.slice(0, limit),
39
+ omittedFolders: Math.max(0, ranked.length - limit),
40
+ };
41
+ }
@@ -326,7 +326,11 @@ export class JobWorkerHost {
326
326
  }
327
327
  if (child.exitCode !== null || child.signalCode !== null) {
328
328
  const evidence = await this.exits.get(child);
329
- throw new ServiceError('JOB_WORKER_EXIT', evidence === undefined ? WORKER_EXIT_MESSAGE : classifyWorkerExit(evidence).message);
329
+ const message = evidence === undefined ? WORKER_EXIT_MESSAGE : classifyWorkerExit(evidence).message;
330
+ // The job's last progress report says how far the worker got before it stopped.
331
+ throw new ServiceError('JOB_WORKER_EXIT', record.progress === undefined
332
+ ? message
333
+ : `${message}; last progress: ${record.progress.message.slice(0, 160)}`);
330
334
  }
331
335
  await delay(100);
332
336
  }
@@ -194,6 +194,9 @@ export function collectMapScriptReferences(files) {
194
194
  const entity = fieldEntity(file.relativePath, key);
195
195
  if (entity === undefined)
196
196
  return;
197
+ // State ids start at 1: `state = 0` (usually `NOT = { state = 0 }`) tests for a valid state.
198
+ if (entity === 'state' && Number(entry.value.value) === 0)
199
+ return;
197
200
  references.push({
198
201
  entity,
199
202
  id: Number(entry.value.value),
@@ -216,6 +219,28 @@ export function missingMapReferenceDiagnostics(references, exists) {
216
219
  if (exists[reference.entity](reference.id))
217
220
  continue;
218
221
  const owned = reference.file.rootKind === 'mod' || reference.file.rootKind === 'fixture';
222
+ if (reference.entity === 'state' &&
223
+ reference.form === 'list' &&
224
+ STATE_LIST_BLOCKS.has(reference.key) &&
225
+ exists.province(reference.id)) {
226
+ // The game's documentation gives `prioritize` state ids only; a province id there (vanilla
227
+ // pairs a state with a port, `prioritize = { 521 7564 }`) is a separate, milder finding.
228
+ diagnostics.push({
229
+ code: 'MAP_SCRIPT_PRIORITIZE_PROVINCE',
230
+ severity: owned ? 'warning' : 'info',
231
+ category: 'map',
232
+ message: `${reference.file.relativePath} lists ${reference.id} in prioritize, which the map defines as a province, not a state; the effects documentation gives prioritize state ids only`,
233
+ location: nodeLocation(reference.document, reference.node),
234
+ details: {
235
+ entity: reference.entity,
236
+ id: reference.id,
237
+ key: reference.key,
238
+ form: reference.form,
239
+ layer: reference.file.rootKind,
240
+ },
241
+ });
242
+ continue;
243
+ }
219
244
  diagnostics.push({
220
245
  code: 'MAP_SCRIPT_REFERENCE_MISSING',
221
246
  severity: owned ? 'error' : 'warning',
@@ -433,7 +458,7 @@ export function mapScriptConsistency(index) {
433
458
  province: (id) => index.definitionsById.has(id),
434
459
  'strategic-region': (id) => index.regionsById.has(id),
435
460
  });
436
- const missing = diagnostics.length;
461
+ const missing = diagnostics.filter(({ code }) => code === 'MAP_SCRIPT_REFERENCE_MISSING').length;
437
462
  const tags = declaredCountryTags(index.sourceFiles);
438
463
  if (tags !== undefined)
439
464
  for (const state of index.states) {
@@ -6,6 +6,8 @@ import { borderQualityInputFromIndex } from './border-quality-input.js';
6
6
  import { borderEdgePixels, forEachBorderEdge, measureBorderNaturalness } from './border-quality.js';
7
7
  import { buildMapCatalog } from './catalog.js';
8
8
  import { validateMapAsync } from './validation.js';
9
+ /** Position records named in a review diff artifact, per kind; the rest are counted. */
10
+ export const MAP_DIFF_POSITION_RECORD_LIMIT = 2_000;
9
11
  function stableColor(key) {
10
12
  const hash = sha256Bytes(key);
11
13
  const first = Number.parseInt(hash.slice(0, 2), 16);
@@ -313,10 +315,13 @@ async function applyOverlays(index, bytes, overlays, signal) {
313
315
  }
314
316
  }
315
317
  }
316
- async function renderMetadata(index, options, signal) {
318
+ async function renderMetadata(index, options, signal, positionRecords = 'all') {
317
319
  const catalog = buildMapCatalog(index);
318
320
  return {
319
321
  ...catalog,
322
+ ...(positionRecords === 'counts'
323
+ ? { buildingPositions: [], unitPositions: [], weatherPositions: [], positionRecords }
324
+ : {}),
320
325
  renderer: 'hoi4-agent-tools-map-workbench',
321
326
  layer: options.layer,
322
327
  overlays: options.overlays,
@@ -486,7 +491,7 @@ export async function renderMap(index, options = {}) {
486
491
  }
487
492
  const png = await encodePng(raw, raster.width, raster.height, resolved.scale);
488
493
  options.signal?.throwIfAborted();
489
- const json = `${canonicalJson(await renderMetadata(index, resolved, options.signal))}\n`;
494
+ const json = `${canonicalJson(await renderMetadata(index, resolved, options.signal, options.positionRecords))}\n`;
490
495
  const provinceHitMap = await encodeProvinceHitMap(index);
491
496
  const html = htmlDocument(`HOI4 map - ${resolved.layer}`, png, provinceHitMap, json, resolved.scale);
492
497
  return {
@@ -693,6 +698,27 @@ export function semanticMapDiff(before, after) {
693
698
  normalAdjacenciesChanged: normalAdjacencies.length > 0,
694
699
  };
695
700
  }
701
+ /**
702
+ * The semantic diff for the artifact, with at most `MAP_DIFF_POSITION_RECORD_LIMIT` building,
703
+ * unit and weather position changes listed per kind: a replaced world changes every position,
704
+ * which would make the review artifact hundreds of megabytes. The counts stay complete.
705
+ */
706
+ export function boundedPositionDiffs(semantic) {
707
+ const kinds = ['buildingPositions', 'unitPositions', 'weatherPositions'];
708
+ const over = kinds.filter((kind) => semantic[kind].length > MAP_DIFF_POSITION_RECORD_LIMIT);
709
+ if (over.length === 0)
710
+ return { semantic };
711
+ const bounded = { ...semantic };
712
+ const positionChanges = {};
713
+ for (const kind of over) {
714
+ bounded[kind] = semantic[kind].slice(0, MAP_DIFF_POSITION_RECORD_LIMIT);
715
+ positionChanges[kind] = {
716
+ total: semantic[kind].length,
717
+ listed: MAP_DIFF_POSITION_RECORD_LIMIT,
718
+ };
719
+ }
720
+ return { semantic: bounded, positionChanges };
721
+ }
696
722
  function uniqueNumbers(values) {
697
723
  return [...new Set(values)].sort((left, right) => left - right);
698
724
  }
@@ -744,7 +770,7 @@ export async function renderMapDiff(before, after, options = {}) {
744
770
  renderer: 'hoi4-agent-tools-map-diff',
745
771
  changedBounds: changedBounds ?? null,
746
772
  changedProvinceIds: [...changedProvinceIds].sort((a, b) => a - b),
747
- semantic,
773
+ ...boundedPositionDiffs(semantic),
748
774
  ...(options.review === undefined ? {} : { review: options.review }),
749
775
  };
750
776
  const json = `${canonicalJson(metadata)}\n`;
@@ -577,6 +577,7 @@ async function wholeMapDiff(after, options) {
577
577
  const rendered = await renderMap(after, {
578
578
  layer: 'state',
579
579
  overlays: ['coastlines', 'ports', 'victory-points', 'supply-nodes', 'railways'],
580
+ positionRecords: 'counts',
580
581
  ...(options?.scale === undefined ? {} : { scale: options.scale }),
581
582
  ...(options?.signal === undefined ? {} : { signal: options.signal }),
582
583
  ...(options?.budget === undefined ? {} : { budget: options.budget }),
@@ -1238,6 +1239,7 @@ export class AgentNudger {
1238
1239
  ? renderMap(snapshot.index, {
1239
1240
  layer: 'state',
1240
1241
  overlays: [...comparisonOverlays],
1242
+ positionRecords: 'counts',
1241
1243
  ...(options.scale === undefined ? {} : { scale: options.scale }),
1242
1244
  ...(options.signal === undefined ? {} : { signal: options.signal }),
1243
1245
  budget,
@@ -1246,6 +1248,7 @@ export class AgentNudger {
1246
1248
  renderMap(plan.finalIndex, {
1247
1249
  layer: 'state',
1248
1250
  overlays: [...comparisonOverlays],
1251
+ positionRecords: 'counts',
1249
1252
  ...(options.scale === undefined ? {} : { scale: options.scale }),
1250
1253
  ...(options.signal === undefined ? {} : { signal: options.signal }),
1251
1254
  budget,
@@ -6,6 +6,7 @@ import { autonomousResultArtifacts, } from '../core/transaction-execution.js';
6
6
  import { emptyServiceResult, ServiceError } from '../core/result.js';
7
7
  import { setInlineFilesScanned } from '../core/operation-result.js';
8
8
  import { PACKAGE_VERSION } from '../version.js';
9
+ import { summarizeChangedFiles } from '../core/changed-summary.js';
9
10
  import { allocateMapIdentifiersAsync, WORLD_OUTPUT_PATH_SAMPLE, } from './operations.js';
10
11
  import { compactTerritoryReport } from './territory-operations.js';
11
12
  import { borderQualityDiagnostics } from './border-quality.js';
@@ -360,6 +361,10 @@ export function completeMapRewrite(workspaceId, execution, recipe) {
360
361
  ...parsed.data,
361
362
  fileCount: transaction.files.length,
362
363
  artifactCount: transaction.artifacts.length,
364
+ // The file list is cut to 100 and a long response is cut again; the counts always arrive.
365
+ ...(execution.outcome === 'applied'
366
+ ? { changedSummary: summarizeChangedFiles(transaction.files) }
367
+ : {}),
363
368
  });
364
369
  result.status = transaction.validation.passed ? 'ok' : 'blocked';
365
370
  result.code =
@@ -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.6.4';
3
+ export const PACKAGE_VERSION = '4.6.5';
4
4
  export const MCP_PROTOCOL_VERSION = LATEST_PROTOCOL_VERSION;
5
5
  export const CONFIG_VERSION = 1;
6
6
  export const TRANSACTION_VERSION = 2;
package/docs/map.md CHANGED
@@ -426,14 +426,15 @@ Measured on project-owned synthetic fixtures (ADR 0060): country-border enrichme
426
426
 
427
427
  `hoi4.map_rewrite` also moves and merges states, moves provinces between strategic regions, merges or removes provinces, changes province definitions and types, adds or removes normal and special adjacency, and updates supply, railway, building, unit, weather, and entity-locator records. Send one ordered operation list when several connected changes belong together.
428
428
 
429
- Every rewrite returns changed-area, changed-ID, semantic, affected-file, diagnostic, and rendered comparison evidence. A failed operation does not leave a partial multi-file result.
429
+ Every rewrite returns changed-area, changed-ID, semantic, affected-file, diagnostic, and rendered comparison evidence. A failed operation does not leave a partial multi-file result. The before and proposed renders (`map-before.*`, `map-proposed.*`) draw every overlay but list building, unit and weather positions only as counts (`positionRecords: "counts"`); `hoi4.map_inspect` returns the records. `map-diff.json` lists at most 2,000 changed building, unit and weather positions per kind and gives the full number in `positionChanges`. The review of a replaced world, where every position changes, would otherwise reach hundreds of megabytes.
430
430
 
431
431
  ## Check script references
432
432
 
433
433
  Set `references: true` on `hoi4.map_inspect` to also read events, focuses, decisions, scripted effects and triggers, on-actions, ideas, characters, AI strategies and areas, and country and unit history.
434
434
  It reports:
435
435
 
436
- - `MAP_SCRIPT_REFERENCE_MISSING`: a state, province or strategic region named by number that the map does not define, as `owns_state = 64`, `has_full_control_of_state = 64`, `transfer_state = 64`, `set_state_controller = 64`, `capital = 64`, a state scope `64 = { ... }`, a `prioritize = { 64 65 }` list, a `state`, `to_state` or `start_state` argument, a province argument such as `set_province_controller` or `province = { id = 3314 }`, a strategic region in `region = 12` or `ships_in_area`, a unit `location`, or an AI area's `strategic_regions`; an error in the mod's own files and a warning in game or dependency files;
436
+ - `MAP_SCRIPT_REFERENCE_MISSING`: a state, province or strategic region named by number that the map does not define, as `owns_state = 64`, `has_full_control_of_state = 64`, `transfer_state = 64`, `set_state_controller = 64`, `capital = 64`, a state scope `64 = { ... }`, a `prioritize = { 64 65 }` list, a `state`, `to_state` or `start_state` argument, a province argument such as `set_province_controller` or `province = { id = 3314 }`, a strategic region in `region = 12` or `ships_in_area`, a unit `location`, or an AI area's `strategic_regions`; an error in the mod's own files and a warning in game or dependency files; `state = 0` (as in `NOT = { state = 0 }`, a test for a valid state) is not a reference;
437
+ - `MAP_SCRIPT_PRIORITIZE_PROVINCE`: a number in a `prioritize` list that the map defines as a province, not a state; `prioritize` takes state ids, so the entry is reported on its own (a warning in the mod's files, information in game or dependency files) and not as a missing reference;
437
438
  - `MAP_STATE_TAG_UNKNOWN`: a state owner, controller, core or claim whose tag no `common/country_tags` file declares;
438
439
  - `MAP_COUNTRY_CAPITAL_NOT_OWNED`: a country that owns states but has its capital in another country's state.
439
440
 
@@ -517,6 +518,8 @@ The operation writes `provinces.bmp`, `definition.csv`, `default.map`, `continen
517
518
 
518
519
  Each write records its generated files in `.hoi4-agent-world.json`. A later `create_world` deletes the recorded files it no longer writes (retires them) in the same transaction and refuses with `MANAGED_OUTPUT_EDITED` when a recorded file was edited since. `MAP_WORLD_OUTPUTS_RECONCILED` and `data.outputs` give the counts of written, retired and released files with up to 200 paths each; `map-world-outputs.json` lists them all.
519
520
 
521
+ Every applied map rewrite also returns `data.changedSummary` with the number of changed files (`total`, `created`, `removed`, `modified`) and the same counts for the 40 folders with the most changes (two levels deep, `.` for the mod root, `omittedFolders` for the rest), so the size of a write is visible even when the inline `changedFiles` list is cut.
522
+
520
523
  ### Countries the mod already owns
521
524
 
522
525
  A mod that writes its own country tags, country files, histories, orders of battle, flags and names gives `countries` as an object instead of an array (ADR 0069):
@@ -37,17 +37,18 @@ This page lists the codes you are most likely to meet, then the checks for probl
37
37
 
38
38
  Use the error code to find what prevented a focus, GUI or map edit.
39
39
 
40
- | Code | Cause and fix |
41
- | ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
42
- | `TRANSACTION_STALE` | A source file changed after the review was made. Inspect again and repeat the rewrite on the current source. |
43
- | `TRANSACTION_RECOVERY_REQUIRED` | An earlier rewrite was interrupted and its journal could not be recovered yet. Reads still work; the message names the reason. Restart the server, and repair the named file if it persists. |
44
- | `TRANSACTION_ROLLBACK_STALE` | A file changed since the rewrite, so it cannot be rolled back safely. Restore the file from version control. |
45
- | `MAP_STATE_DISTRIBUTION_REQUIRED` | A state operation was given an incomplete explicit policy. Omit `distribution` for the automatic land-share policy, or send every field (see [Maps](map.md)). |
46
- | `MAP_STATE_REGION_DISTRIBUTION_CONFLICT` | Moved or merged provinces lie in different strategic regions. Use `strategicRegion: "move-to-target-region"`, or move the provinces between regions first. |
47
- | `MAP_EXTERNAL_REFERENCE_READ_ONLY` | Base-game or dependency scripts name a changed state. Repeat with `remapReferences` or `readOnlySources` set to `override` to copy them into the mod with the numbers changed. |
48
- | `MAP_DATED_STATE_HISTORY_CONFLICT` | A dated block (`1939.1.1 = { ... }`) overrides the value you are changing. Edit that block, or change the later date's value deliberately. |
49
- | `MAP_SCRIPT_REFERENCE_MISSING` (error) | A script names a state, province or region the map does not define. Remap it with `remap_map_references`, or correct the script. |
50
- | `MAP_REFERENCE_NEEDS_REVIEW` (info) | A single-valued argument such as `capital = 64` had no single successor and was left as it was. Choose its new target by hand. |
40
+ | Code | Cause and fix |
41
+ | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
42
+ | `TRANSACTION_STALE` | A source file changed after the review was made. Inspect again and repeat the rewrite on the current source. |
43
+ | `TRANSACTION_RECOVERY_REQUIRED` | An earlier rewrite was interrupted and its journal could not be recovered yet. Reads still work; the message names the reason. Restart the server, and repair the named file if it persists. |
44
+ | `TRANSACTION_ROLLBACK_STALE` | A file changed since the rewrite, so it cannot be rolled back safely. Restore the file from version control. |
45
+ | `MAP_STATE_DISTRIBUTION_REQUIRED` | A state operation was given an incomplete explicit policy. Omit `distribution` for the automatic land-share policy, or send every field (see [Maps](map.md)). |
46
+ | `MAP_STATE_REGION_DISTRIBUTION_CONFLICT` | Moved or merged provinces lie in different strategic regions. Use `strategicRegion: "move-to-target-region"`, or move the provinces between regions first. |
47
+ | `MAP_EXTERNAL_REFERENCE_READ_ONLY` | Base-game or dependency scripts name a changed state. Repeat with `remapReferences` or `readOnlySources` set to `override` to copy them into the mod with the numbers changed. |
48
+ | `MAP_DATED_STATE_HISTORY_CONFLICT` | A dated block (`1939.1.1 = { ... }`) overrides the value you are changing. Edit that block, or change the later date's value deliberately. |
49
+ | `MAP_SCRIPT_REFERENCE_MISSING` (error) | A script names a state, province or region the map does not define. Remap it with `remap_map_references`, or correct the script. |
50
+ | `MAP_SCRIPT_PRIORITIZE_PROVINCE` | A `prioritize = { ... }` list holds a province id where the effects documentation gives state ids only (vanilla pairs states with ports, `prioritize = { 521 7564 }`). Replace it with the state that holds the province. |
51
+ | `MAP_REFERENCE_NEEDS_REVIEW` (info) | A single-valued argument such as `capital = 64` had no single successor and was left as it was. Choose its new target by hand. |
51
52
 
52
53
  ## Game and live testing
53
54
 
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "hoi4-agent-tools",
3
- "version": "4.6.4",
3
+ "version": "4.6.5",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "hoi4-agent-tools",
9
- "version": "4.6.4",
9
+ "version": "4.6.5",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
12
  "@fontsource-variable/roboto": "5.3.0",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "hoi4-agent-tools",
3
3
  "mcpName": "io.github.klimPaskov/hoi4-agent-tools",
4
- "version": "4.6.4",
4
+ "version": "4.6.5",
5
5
  "description": "Build HOI4 mods: focus trees, events, decisions, worlds, GUI previews, docs and AI balance.",
6
6
  "type": "module",
7
7
  "license": "Apache-2.0",
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/configuration.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/configuration.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/continuous-focus-palette.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/continuous-focus-palette.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/custom-weighted-pool.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/custom-weighted-pool.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/decision-inspect-input.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/decision-inspect-input.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/error-log-input.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/error-log-input.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/event-feature-manifest.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/event-feature-manifest.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/focus-plan.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/focus-plan.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/focus-planning-sidecar.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/focus-planning-sidecar.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/geography-model.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/geography-model.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/gui-animation-source.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/gui-animation-source.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/gui-helper.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/gui-helper.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/gui-scenario.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/gui-scenario.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/helper-expansion-request.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/helper-expansion-request.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/helper-expansion-summary.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/helper-expansion-summary.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/impact-inspect-input.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/impact-inspect-input.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/map-operation.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/map-operation.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "oneOf": [
5
5
  {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/mechanic-test-input.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/mechanic-test-input.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/mod-index-input.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/mod-index-input.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/operation-result.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/operation-result.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/package-check-input.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/package-check-input.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/package-manifest.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/package-manifest.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/probability-analysis-result.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/probability-analysis-result.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/probability-compare-input.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/probability-compare-input.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/probability-evaluate-input.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/probability-evaluate-input.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/probability-inspect-input.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/probability-inspect-input.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/probability-render-input.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/probability-render-input.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/probability-scenario-set.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/probability-scenario-set.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/probability-sequence-input.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/probability-sequence-input.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/probability-simulate-input.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/probability-simulate-input.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/probability-sweep-input.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/probability-sweep-input.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/reference-context-input.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/reference-context-input.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/reference-read-input.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/reference-read-input.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/reference-search-input.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/reference-search-input.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/reference-sheets.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/reference-sheets.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/scenario-suite.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/scenario-suite.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/scenario-test-input.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/scenario-test-input.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/script-validate-input.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/script-validate-input.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/shared-scenario.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/shared-scenario.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.4/schemas/source-lookup-input.schema.json",
2
+ "$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v4.6.5/schemas/source-lookup-input.schema.json",
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "type": "object",
5
5
  "properties": {
package/server.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "name": "io.github.klimPaskov/hoi4-agent-tools",
4
4
  "title": "HOI4 Agent Tools",
5
5
  "description": "Build HOI4 mods: focus trees, events, decisions, worlds, GUI previews, docs and AI balance.",
6
- "version": "4.6.4",
6
+ "version": "4.6.5",
7
7
  "repository": {
8
8
  "url": "https://github.com/klimPaskov/hoi4-agent-tools",
9
9
  "source": "github"
@@ -13,7 +13,7 @@
13
13
  {
14
14
  "registryType": "npm",
15
15
  "identifier": "hoi4-agent-tools",
16
- "version": "4.6.4",
16
+ "version": "4.6.5",
17
17
  "transport": {
18
18
  "type": "stdio"
19
19
  }