hoi4-agent-tools 4.3.0 → 4.5.0

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 (119) hide show
  1. package/CHANGELOG.md +33 -1
  2. package/dist/hoi4_agent_tools/core/bounded-source.js +31 -9
  3. package/dist/hoi4_agent_tools/core/configuration.js +11 -0
  4. package/dist/hoi4_agent_tools/core/managed-outputs.js +26 -6
  5. package/dist/hoi4_agent_tools/core/operation-context.js +17 -1
  6. package/dist/hoi4_agent_tools/core/source/encoding.js +56 -2
  7. package/dist/hoi4_agent_tools/core/source/parser.js +16 -1
  8. package/dist/hoi4_agent_tools/core/temporary-directories.js +7 -2
  9. package/dist/hoi4_agent_tools/core/transaction-limits.js +18 -4
  10. package/dist/hoi4_agent_tools/core/transactions.js +23 -4
  11. package/dist/hoi4_agent_tools/core/workspace-json.js +54 -0
  12. package/dist/hoi4_agent_tools/core/workspace.js +42 -6
  13. package/dist/hoi4_agent_tools/focus/drift.js +34 -0
  14. package/dist/hoi4_agent_tools/focus/service.js +9 -3
  15. package/dist/hoi4_agent_tools/focus/tool-operations.js +2 -0
  16. package/dist/hoi4_agent_tools/map/appearance-validation.js +1110 -0
  17. package/dist/hoi4_agent_tools/map/bmp.js +9 -1
  18. package/dist/hoi4_agent_tools/map/border-quality-input.js +209 -0
  19. package/dist/hoi4_agent_tools/map/border-quality.js +1180 -0
  20. package/dist/hoi4_agent_tools/map/colormap.js +128 -0
  21. package/dist/hoi4_agent_tools/map/geography/geometry.js +284 -0
  22. package/dist/hoi4_agent_tools/map/geography/index.js +6 -0
  23. package/dist/hoi4_agent_tools/map/geography/model.js +196 -0
  24. package/dist/hoi4_agent_tools/map/geography/preparation.js +120 -0
  25. package/dist/hoi4_agent_tools/map/geography/preview.js +647 -0
  26. package/dist/hoi4_agent_tools/map/geography/raster.js +253 -0
  27. package/dist/hoi4_agent_tools/map/geography/resolve.js +1467 -0
  28. package/dist/hoi4_agent_tools/map/model.js +17 -3
  29. package/dist/hoi4_agent_tools/map/operations.js +284 -14
  30. package/dist/hoi4_agent_tools/map/partition-fields.js +398 -0
  31. package/dist/hoi4_agent_tools/map/partition-geography.js +113 -0
  32. package/dist/hoi4_agent_tools/map/partition-graph.js +165 -0
  33. package/dist/hoi4_agent_tools/map/partition-groups.js +164 -0
  34. package/dist/hoi4_agent_tools/map/partition-provinces.js +727 -0
  35. package/dist/hoi4_agent_tools/map/partition-tuning.js +101 -0
  36. package/dist/hoi4_agent_tools/map/partition-watershed.js +252 -0
  37. package/dist/hoi4_agent_tools/map/partition.js +163 -0
  38. package/dist/hoi4_agent_tools/map/reference-import.js +333 -0
  39. package/dist/hoi4_agent_tools/map/reference-preparation.js +142 -6
  40. package/dist/hoi4_agent_tools/map/reference-sheets.js +231 -0
  41. package/dist/hoi4_agent_tools/map/reference-world.js +104 -13
  42. package/dist/hoi4_agent_tools/map/relief/checks.js +281 -0
  43. package/dist/hoi4_agent_tools/map/relief/fields.js +15 -0
  44. package/dist/hoi4_agent_tools/map/relief/full-resolution.js +133 -0
  45. package/dist/hoi4_agent_tools/map/relief/grid.js +190 -0
  46. package/dist/hoi4_agent_tools/map/relief/hydrology.js +1315 -0
  47. package/dist/hoi4_agent_tools/map/relief/index.js +27 -0
  48. package/dist/hoi4_agent_tools/map/relief/land.js +110 -0
  49. package/dist/hoi4_agent_tools/map/relief/macro-relief.js +535 -0
  50. package/dist/hoi4_agent_tools/map/relief/math.js +93 -0
  51. package/dist/hoi4_agent_tools/map/relief/river-raster.js +680 -0
  52. package/dist/hoi4_agent_tools/map/relief/terrain-synthesis.js +304 -0
  53. package/dist/hoi4_agent_tools/map/render.js +36 -0
  54. package/dist/hoi4_agent_tools/map/service.js +206 -16
  55. package/dist/hoi4_agent_tools/map/tool-operations.js +249 -3
  56. package/dist/hoi4_agent_tools/map/validation.js +9 -0
  57. package/dist/hoi4_agent_tools/map/water.js +227 -0
  58. package/dist/hoi4_agent_tools/map/world-context.js +47 -1
  59. package/dist/hoi4_agent_tools/map/world-edge.js +335 -0
  60. package/dist/hoi4_agent_tools/map/world-noise.js +34 -0
  61. package/dist/hoi4_agent_tools/map/world-outputs.js +22 -10
  62. package/dist/hoi4_agent_tools/map/world-partition.js +119 -0
  63. package/dist/hoi4_agent_tools/map/world-provinces.js +131 -56
  64. package/dist/hoi4_agent_tools/map/world-realms.js +152 -0
  65. package/dist/hoi4_agent_tools/map/world.js +562 -163
  66. package/dist/hoi4_agent_tools/mcp/tools/map.js +69 -1
  67. package/dist/hoi4_agent_tools/reference/operations.js +3 -2
  68. package/dist/hoi4_agent_tools/schemas/geography.js +325 -0
  69. package/dist/hoi4_agent_tools/schemas/map-requests.js +20 -2
  70. package/dist/hoi4_agent_tools/schemas/map.js +280 -15
  71. package/dist/hoi4_agent_tools/schemas/reference-sheets.js +92 -0
  72. package/dist/hoi4_agent_tools/version.js +1 -1
  73. package/docs/configuration.md +17 -14
  74. package/docs/focus.md +6 -0
  75. package/docs/map.md +292 -15
  76. package/docs/tools.md +4 -4
  77. package/docs/troubleshooting.md +11 -11
  78. package/npm-shrinkwrap.json +109 -91
  79. package/package.json +3 -3
  80. package/schemas/configuration.schema.json +65 -58
  81. package/schemas/continuous-focus-palette.schema.json +1 -1
  82. package/schemas/custom-weighted-pool.schema.json +1 -1
  83. package/schemas/decision-inspect-input.schema.json +1 -1
  84. package/schemas/error-log-input.schema.json +1 -1
  85. package/schemas/event-feature-manifest.schema.json +1 -1
  86. package/schemas/focus-plan.schema.json +1 -1
  87. package/schemas/focus-planning-sidecar.schema.json +1 -1
  88. package/schemas/geography-model.schema.json +1148 -0
  89. package/schemas/gui-animation-source.schema.json +1 -1
  90. package/schemas/gui-helper.schema.json +5 -11
  91. package/schemas/gui-scenario.schema.json +1 -1
  92. package/schemas/helper-expansion-request.schema.json +1 -1
  93. package/schemas/helper-expansion-summary.schema.json +1 -1
  94. package/schemas/impact-inspect-input.schema.json +1 -1
  95. package/schemas/map-operation.schema.json +2325 -292
  96. package/schemas/mechanic-test-input.schema.json +1 -1
  97. package/schemas/mod-index-input.schema.json +1 -1
  98. package/schemas/operation-result.schema.json +1 -1
  99. package/schemas/package-check-input.schema.json +1 -1
  100. package/schemas/package-manifest.schema.json +1 -1
  101. package/schemas/probability-analysis-result.schema.json +25 -7
  102. package/schemas/probability-compare-input.schema.json +1 -1
  103. package/schemas/probability-evaluate-input.schema.json +1 -1
  104. package/schemas/probability-inspect-input.schema.json +1 -1
  105. package/schemas/probability-render-input.schema.json +1 -1
  106. package/schemas/probability-scenario-set.schema.json +1 -1
  107. package/schemas/probability-sequence-input.schema.json +1 -1
  108. package/schemas/probability-simulate-input.schema.json +1 -1
  109. package/schemas/probability-sweep-input.schema.json +1 -1
  110. package/schemas/reference-context-input.schema.json +1 -1
  111. package/schemas/reference-read-input.schema.json +1 -1
  112. package/schemas/reference-search-input.schema.json +1 -1
  113. package/schemas/reference-sheets.schema.json +267 -0
  114. package/schemas/scenario-suite.schema.json +1 -1
  115. package/schemas/scenario-test-input.schema.json +1 -1
  116. package/schemas/script-validate-input.schema.json +1 -1
  117. package/schemas/shared-scenario.schema.json +1 -1
  118. package/schemas/source-lookup-input.schema.json +1 -1
  119. package/server.json +2 -2
@@ -0,0 +1,164 @@
1
+ /** A binary max-heap keyed by score, then by the lower ids. */
2
+ class CandidateHeap {
3
+ #items = [];
4
+ get size() {
5
+ return this.#items.length;
6
+ }
7
+ static #before(x, y) {
8
+ if (x.score !== y.score)
9
+ return x.score > y.score;
10
+ if (x.a !== y.a)
11
+ return x.a < y.a;
12
+ return x.b < y.b;
13
+ }
14
+ push(item) {
15
+ const items = this.#items;
16
+ let i = items.length;
17
+ items.push(item);
18
+ while (i > 0) {
19
+ const parent = (i - 1) >> 1;
20
+ if (!CandidateHeap.#before(items[i], items[parent]))
21
+ break;
22
+ [items[i], items[parent]] = [items[parent], items[i]];
23
+ i = parent;
24
+ }
25
+ }
26
+ pop() {
27
+ const items = this.#items;
28
+ if (items.length === 0)
29
+ return undefined;
30
+ const top = items[0];
31
+ const last = items.pop();
32
+ if (items.length > 0) {
33
+ items[0] = last;
34
+ let i = 0;
35
+ for (;;) {
36
+ const l = i * 2 + 1;
37
+ const r = l + 1;
38
+ let best = i;
39
+ if (l < items.length && CandidateHeap.#before(items[l], items[best]))
40
+ best = l;
41
+ if (r < items.length && CandidateHeap.#before(items[r], items[best]))
42
+ best = r;
43
+ if (best === i)
44
+ break;
45
+ [items[i], items[best]] = [items[best], items[i]];
46
+ i = best;
47
+ }
48
+ }
49
+ return top;
50
+ }
51
+ }
52
+ /**
53
+ * Cluster `members` (province ids) over the graph. Returns the cluster of every member, numbered
54
+ * from 0 by the smallest member id of each cluster.
55
+ */
56
+ export function clusterProvinces(members, graph, options, hooks = {}) {
57
+ const lambda = options.lambda ?? 12;
58
+ const hard = options.hardBarrier ?? 0.6;
59
+ const unlike = options.unlikeGround ?? 0.55;
60
+ const sorted = [...members].sort((a, b) => a - b);
61
+ const local = new Map(sorted.map((id, index) => [id, index]));
62
+ const n = sorted.length;
63
+ const sizeOf = new Int32Array(n).fill(1);
64
+ const perimeter = new Float64Array(n);
65
+ const version = new Int32Array(n);
66
+ const alive = new Uint8Array(n).fill(1);
67
+ const affinity = Array.from({ length: n }, () => new Map());
68
+ const shared = Array.from({ length: n }, () => new Map());
69
+ for (let i = 0; i < n; i++) {
70
+ const id = sorted[i];
71
+ for (let e = graph.offsets[id]; e < graph.offsets[id + 1]; e++) {
72
+ perimeter[i] += graph.length[e];
73
+ const other = local.get(graph.to[e]);
74
+ if (other === undefined || other === i)
75
+ continue;
76
+ if (hooks.group !== undefined && hooks.group(id) !== hooks.group(graph.to[e]))
77
+ continue;
78
+ const strength = graph.barrier[e];
79
+ const damp = 1 / ((1 + lambda * strength) * (1 + lambda * strength));
80
+ let weight = graph.length[e] * damp;
81
+ if (strength > hard)
82
+ weight *= 0.05;
83
+ if (hooks.label !== undefined && hooks.label(id) !== hooks.label(graph.to[e]))
84
+ weight *= unlike;
85
+ affinity[i].set(other, weight);
86
+ shared[i].set(other, graph.length[e]);
87
+ }
88
+ }
89
+ const heap = new CandidateHeap();
90
+ const scoreOf = (a, b) => {
91
+ const total = sizeOf[a] + sizeOf[b];
92
+ if (total > options.max)
93
+ return 0;
94
+ let factor = total <= options.target ? 1 : (options.max - total) / (options.max - options.target + 1);
95
+ const small = Math.min(sizeOf[a], sizeOf[b]) < options.min;
96
+ if (small)
97
+ factor = Math.max(factor, 0.05) * 2;
98
+ if (factor <= 0)
99
+ return 0;
100
+ const base = affinity[a].get(b);
101
+ return (base / Math.sqrt(Math.max(1, perimeter[a]) * Math.max(1, perimeter[b]))) * factor;
102
+ };
103
+ const offer = (a, b) => {
104
+ const low = Math.min(a, b);
105
+ const high = Math.max(a, b);
106
+ const score = scoreOf(low, high);
107
+ if (score > 0)
108
+ heap.push({ score, a: low, b: high, versionA: version[low], versionB: version[high] });
109
+ };
110
+ for (let i = 0; i < n; i++)
111
+ for (const other of affinity[i].keys())
112
+ if (other > i)
113
+ offer(i, other);
114
+ const parent = Int32Array.from({ length: n }, (_, i) => i);
115
+ for (let top = heap.pop(); top !== undefined; top = heap.pop()) {
116
+ const { a, b } = top;
117
+ if (!alive[a] || !alive[b] || version[a] !== top.versionA || version[b] !== top.versionB)
118
+ continue;
119
+ // Merge b into a. Only pairs that involve a change, so only a's version moves on.
120
+ const between = shared[a].get(b) ?? 0;
121
+ perimeter[a] = perimeter[a] + perimeter[b] - 2 * between;
122
+ sizeOf[a] += sizeOf[b];
123
+ alive[b] = 0;
124
+ parent[b] = a;
125
+ affinity[a].delete(b);
126
+ shared[a].delete(b);
127
+ for (const [c, weight] of affinity[b]) {
128
+ if (c === a)
129
+ continue;
130
+ const combined = (affinity[a].get(c) ?? 0) + weight;
131
+ const length = (shared[a].get(c) ?? 0) + (shared[b].get(c) ?? 0);
132
+ affinity[a].set(c, combined);
133
+ shared[a].set(c, length);
134
+ affinity[c].delete(b);
135
+ shared[c].delete(b);
136
+ affinity[c].set(a, combined);
137
+ shared[c].set(a, length);
138
+ }
139
+ affinity[b].clear();
140
+ shared[b].clear();
141
+ version[a]++;
142
+ for (const c of affinity[a].keys())
143
+ offer(a, c);
144
+ }
145
+ // Number clusters by their smallest member (members are sorted, so the first one seen).
146
+ const root = (i) => {
147
+ let r = i;
148
+ while (parent[r] !== r)
149
+ r = parent[r];
150
+ return r;
151
+ };
152
+ const dense = new Map();
153
+ const result = new Map();
154
+ for (let i = 0; i < n; i++) {
155
+ const r = root(i);
156
+ let id = dense.get(r);
157
+ if (id === undefined) {
158
+ id = dense.size;
159
+ dense.set(r, id);
160
+ }
161
+ result.set(sorted[i], id);
162
+ }
163
+ return result;
164
+ }