hoi4-agent-tools 2.3.10 → 2.3.11
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.
- package/CHANGELOG.md +6 -0
- package/dist/hoi4_agent_tools/focus/compact.js +44 -45
- package/dist/hoi4_agent_tools/focus/layout.js +71 -0
- package/dist/hoi4_agent_tools/version.js +1 -1
- package/docs/focus.md +1 -1
- package/package.json +1 -1
- package/schemas/configuration.schema.json +1 -1
- package/schemas/continuous-focus-palette.schema.json +1 -1
- package/schemas/custom-weighted-pool.schema.json +1 -1
- package/schemas/event-feature-manifest.schema.json +1 -1
- package/schemas/focus-plan.schema.json +1 -1
- package/schemas/focus-planning-sidecar.schema.json +1 -1
- package/schemas/gui-animation-source.schema.json +1 -1
- package/schemas/gui-helper.schema.json +1 -1
- package/schemas/gui-scenario.schema.json +1 -1
- package/schemas/map-operation.schema.json +1 -1
- package/schemas/operation-result.schema.json +1 -1
- package/schemas/probability-analysis-result.schema.json +1 -1
- package/schemas/probability-compare-input.schema.json +1 -1
- package/schemas/probability-evaluate-input.schema.json +1 -1
- package/schemas/probability-inspect-input.schema.json +1 -1
- package/schemas/probability-render-input.schema.json +1 -1
- package/schemas/probability-scenario-set.schema.json +1 -1
- package/schemas/probability-sequence-input.schema.json +1 -1
- package/schemas/probability-simulate-input.schema.json +1 -1
- package/schemas/probability-sweep-input.schema.json +1 -1
- package/server.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.3.11 - 2026-08-05
|
|
4
|
+
|
|
5
|
+
- Made compact focus rewrites straighten offset linear chains and reject artificial staircase or zigzag geometry.
|
|
6
|
+
- Tightened compact layout acceptance so long connectors, connector paths through focuses, crossings, asymmetric sibling groups, and off-anchor branches cannot survive a successful cleanup.
|
|
7
|
+
- Kept the stricter rewrite deterministic and verified it through the public 1,024-focus MCP workflow.
|
|
8
|
+
|
|
3
9
|
## 2.3.10 - 2026-08-04
|
|
4
10
|
|
|
5
11
|
- Routed focus operations to the unique discovered mod containing a requested source when a stale client root points at another mod.
|
|
@@ -10,14 +10,18 @@ const LARGE_COMPACT_SCALES = [0.55, 0.6, 0.7, 0.8];
|
|
|
10
10
|
const COMPACT_LAYOUT_WORK_MAX = FOCUS_LAYOUT_WORK_MAX * 10;
|
|
11
11
|
const COMPACT_HARD_DIAGNOSTICS = new Set([
|
|
12
12
|
'FOCUS_LAYOUT_CONNECTOR_CROSSING_UNSATISFIED',
|
|
13
|
+
'FOCUS_LAYOUT_CONNECTOR_THROUGH_NODE',
|
|
13
14
|
'FOCUS_LAYOUT_COORDINATE_CONFLICT',
|
|
15
|
+
'FOCUS_LAYOUT_LINEAR_DETOUR',
|
|
14
16
|
'FOCUS_LAYOUT_LANE_BOUNDS_UNSATISFIED',
|
|
15
17
|
'FOCUS_LAYOUT_MUTUAL_EXCLUSION_SPACING_UNSATISFIED',
|
|
16
18
|
'FOCUS_LAYOUT_PARENT_ORDER_UNSATISFIED',
|
|
17
19
|
'FOCUS_LAYOUT_SAME_ROW_SPACING_UNSATISFIED',
|
|
20
|
+
'FOCUS_LAYOUT_STAIRCASE_CHAIN',
|
|
18
21
|
'FOCUS_LAYOUT_VISIBLE_OVERLAP',
|
|
22
|
+
'FOCUS_LAYOUT_ZIGZAG_CHAIN',
|
|
19
23
|
]);
|
|
20
|
-
function compactLimits(focusCount
|
|
24
|
+
function compactLimits(focusCount) {
|
|
21
25
|
const graphScale = Math.sqrt(Math.max(1, focusCount));
|
|
22
26
|
const maximumHorizontalSpan = Math.max(14, Math.ceil(graphScale * 3));
|
|
23
27
|
const maximumVerticalSpan = Math.max(4, Math.ceil(Math.log2(Math.max(2, focusCount))));
|
|
@@ -26,10 +30,6 @@ function compactLimits(focusCount, connectorCount) {
|
|
|
26
30
|
maximumHorizontalSpan,
|
|
27
31
|
maximumVerticalSpan,
|
|
28
32
|
maximumManhattanSpan: maximumHorizontalSpan + maximumVerticalSpan,
|
|
29
|
-
maximumLongConnectors: Math.ceil(connectorCount * 0.05),
|
|
30
|
-
maximumNodeIntersections: Math.ceil(connectorCount * 0.12),
|
|
31
|
-
maximumSiblingDeviation: Math.max(2, Math.ceil(graphScale * 2)),
|
|
32
|
-
maximumTotalSiblingDeviation: Math.max(4, Math.ceil(focusCount * 0.5)),
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
35
|
function requiredMetrics(layout) {
|
|
@@ -39,26 +39,18 @@ function requiredMetrics(layout) {
|
|
|
39
39
|
}
|
|
40
40
|
function absoluteCompactRegressions(layout) {
|
|
41
41
|
const metrics = requiredMetrics(layout);
|
|
42
|
-
const limits = compactLimits(layout.nodes.length
|
|
42
|
+
const limits = compactLimits(layout.nodes.length);
|
|
43
43
|
return [
|
|
44
44
|
...(layout.diagnostics.some(({ code }) => COMPACT_HARD_DIAGNOSTICS.has(code))
|
|
45
45
|
? ['hardLayoutDiagnostics']
|
|
46
46
|
: []),
|
|
47
47
|
...(metrics.connectors.crossingCount > 0 ? ['connectorCrossingCount'] : []),
|
|
48
|
-
...(metrics.connectors.nodeIntersectionCount >
|
|
49
|
-
? ['connectorNodeIntersectionBudget']
|
|
50
|
-
: []),
|
|
48
|
+
...(metrics.connectors.nodeIntersectionCount > 0 ? ['connectorNodeIntersections'] : []),
|
|
51
49
|
...(metrics.spacing.tooCloseSameRowPairCount > 0 ? ['sameRowSpacing'] : []),
|
|
52
|
-
...(metrics.symmetry.
|
|
53
|
-
...(metrics.symmetry.totalSiblingDeviation >
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
...(metrics.symmetry.maximumSiblingAnchorDeviation > limits.maximumSiblingDeviation
|
|
57
|
-
? ['maximumSiblingDeviationBudget']
|
|
58
|
-
: []),
|
|
59
|
-
...(metrics.symmetry.totalSiblingAnchorDeviation > limits.maximumTotalSiblingDeviation
|
|
60
|
-
? ['totalSiblingDeviationBudget']
|
|
61
|
-
: []),
|
|
50
|
+
...(metrics.symmetry.asymmetricSiblingCohortCount > 0 ? ['siblingMirrorDeviation'] : []),
|
|
51
|
+
...(metrics.symmetry.totalSiblingDeviation > 0 ? ['totalSiblingMirrorDeviation'] : []),
|
|
52
|
+
...(metrics.symmetry.offAnchorSiblingCohortCount > 0 ? ['siblingAnchorDeviation'] : []),
|
|
53
|
+
...(metrics.symmetry.totalSiblingAnchorDeviation > 0 ? ['totalSiblingAnchorDeviation'] : []),
|
|
62
54
|
...(metrics.symmetry.boundingCenterOffsetTwice > 1 ? ['boundingCenter'] : []),
|
|
63
55
|
...(metrics.bounds.columnCount > limits.maximumColumns ? ['columnBudget'] : []),
|
|
64
56
|
...(metrics.connectors.maximumHorizontalSpan > limits.maximumHorizontalSpan
|
|
@@ -70,9 +62,7 @@ function absoluteCompactRegressions(layout) {
|
|
|
70
62
|
...(metrics.connectors.maximumManhattanSpan > limits.maximumManhattanSpan
|
|
71
63
|
? ['maximumManhattanConnectorBudget']
|
|
72
64
|
: []),
|
|
73
|
-
...(metrics.connectors.longConnectorCount >
|
|
74
|
-
? ['longConnectorBudget']
|
|
75
|
-
: []),
|
|
65
|
+
...(metrics.connectors.longConnectorCount > 0 ? ['longConnectors'] : []),
|
|
76
66
|
];
|
|
77
67
|
}
|
|
78
68
|
function relativeCompactRegressions(current, proposed) {
|
|
@@ -161,11 +151,8 @@ function compactStructuralAnchorX(plan, focus, parents, preferredX, laneBases) {
|
|
|
161
151
|
function mirrorSiblingCohorts(plan, preferredX, preferredY) {
|
|
162
152
|
const cohorts = new Map();
|
|
163
153
|
const laneBases = compactLaneBases(plan);
|
|
164
|
-
const childCounts = new Map();
|
|
165
154
|
for (const focus of plan.focuses) {
|
|
166
155
|
const parents = prerequisiteIds(plan, focus.id);
|
|
167
|
-
for (const parentId of parents)
|
|
168
|
-
childCounts.set(parentId, (childCounts.get(parentId) ?? 0) + 1);
|
|
169
156
|
const key = JSON.stringify([
|
|
170
157
|
parents.length === 0 ? focusLaneId(plan, focus) : null,
|
|
171
158
|
parents,
|
|
@@ -184,11 +171,6 @@ function mirrorSiblingCohorts(plan, preferredX, preferredY) {
|
|
|
184
171
|
const focus = plan.focuses.find(({ id }) => id === cohort[0]);
|
|
185
172
|
if (focus === undefined)
|
|
186
173
|
continue;
|
|
187
|
-
// A leaf fan can be mirrored directly around its structural parent. For
|
|
188
|
-
// rooted subtrees, moving only the entry focuses would push the long
|
|
189
|
-
// connectors into their descendants; keep the subtree envelope's center
|
|
190
|
-
// until the bounded gateway refinement can move the common parent.
|
|
191
|
-
const leafFan = cohort.every((focusId) => (childCounts.get(focusId) ?? 0) === 0);
|
|
192
174
|
const mirroredAt = (centerTwice) => {
|
|
193
175
|
const mirrored = [...coordinates];
|
|
194
176
|
for (let index = 0; index < pairCount; index += 1) {
|
|
@@ -209,24 +191,40 @@ function mirrorSiblingCohorts(plan, preferredX, preferredY) {
|
|
|
209
191
|
}
|
|
210
192
|
return mirrored;
|
|
211
193
|
};
|
|
212
|
-
const selfCenterTwice = (coordinates[0] ?? 0) + (coordinates.at(-1) ?? 0);
|
|
213
194
|
const anchorCenterTwice = 2 *
|
|
214
195
|
compactStructuralAnchorX(plan, focus, prerequisiteIds(plan, focus.id), preferredX, laneBases);
|
|
215
|
-
|
|
216
|
-
if (leafFan) {
|
|
217
|
-
const cohortIds = new Set(cohort);
|
|
218
|
-
const y = preferredY.get(cohort[0] ?? '');
|
|
219
|
-
const otherCoordinates = plan.focuses.flatMap((candidate) => !cohortIds.has(candidate.id) && preferredY.get(candidate.id) === y
|
|
220
|
-
? [preferredX.get(candidate.id) ?? 0]
|
|
221
|
-
: []);
|
|
222
|
-
if (mirrored.some((coordinate) => otherCoordinates.some((otherCoordinate) => Math.abs(coordinate - otherCoordinate) < COMPACT_SAME_ROW_SPACING))) {
|
|
223
|
-
mirrored = mirroredAt(selfCenterTwice);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
196
|
+
const mirrored = mirroredAt(anchorCenterTwice);
|
|
226
197
|
for (const [index, focusId] of cohort.entries())
|
|
227
198
|
preferredX.set(focusId, mirrored[index] ?? 0);
|
|
228
199
|
}
|
|
229
200
|
}
|
|
201
|
+
function straightenLinearChains(plan, preferredX, preferredY) {
|
|
202
|
+
const parentIds = new Map(plan.focuses.map((focus) => [focus.id, prerequisiteIds(plan, focus.id)]));
|
|
203
|
+
const childIds = new Map();
|
|
204
|
+
for (const [focusId, parents] of parentIds) {
|
|
205
|
+
for (const parentId of parents) {
|
|
206
|
+
const children = childIds.get(parentId) ?? [];
|
|
207
|
+
children.push(focusId);
|
|
208
|
+
childIds.set(parentId, children);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
const ordered = [...plan.focuses].sort((left, right) => (preferredY.get(left.id) ?? 0) - (preferredY.get(right.id) ?? 0) ||
|
|
212
|
+
compareCodeUnits(left.id, right.id));
|
|
213
|
+
for (const focus of ordered) {
|
|
214
|
+
const parents = parentIds.get(focus.id) ?? [];
|
|
215
|
+
if (parents.length !== 1)
|
|
216
|
+
continue;
|
|
217
|
+
const parentId = parents[0];
|
|
218
|
+
if (parentId === undefined || (childIds.get(parentId)?.length ?? 0) !== 1)
|
|
219
|
+
continue;
|
|
220
|
+
const parentX = preferredX.get(parentId);
|
|
221
|
+
const parentY = preferredY.get(parentId);
|
|
222
|
+
if (parentX === undefined || parentY === undefined)
|
|
223
|
+
continue;
|
|
224
|
+
preferredX.set(focus.id, parentX);
|
|
225
|
+
preferredY.set(focus.id, parentY + 1);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
230
228
|
function compactCandidate(plan, layout, scale, compressRows) {
|
|
231
229
|
const minimumX = Math.min(...layout.nodes.map(({ x }) => x));
|
|
232
230
|
const maximumX = Math.max(...layout.nodes.map(({ x }) => x));
|
|
@@ -259,6 +257,7 @@ function compactCandidate(plan, layout, scale, compressRows) {
|
|
|
259
257
|
preferredX.set(node.id, (placed[index] ?? 0) + drift);
|
|
260
258
|
}
|
|
261
259
|
mirrorSiblingCohorts(plan, preferredX, preferredY);
|
|
260
|
+
straightenLinearChains(plan, preferredX, preferredY);
|
|
262
261
|
const compacted = structuredClone(plan);
|
|
263
262
|
compacted.laneGroups = compacted.laneGroups.map(({ id, label, order }) => ({
|
|
264
263
|
id,
|
|
@@ -328,7 +327,7 @@ export function compactFocusTreePlan(plan) {
|
|
|
328
327
|
let selected;
|
|
329
328
|
let fallback;
|
|
330
329
|
for (const scale of scales) {
|
|
331
|
-
for (const compressRows of
|
|
330
|
+
for (const compressRows of [false, true]) {
|
|
332
331
|
const candidate = compactCandidate(plan, currentLayout, scale, compressRows);
|
|
333
332
|
let layout;
|
|
334
333
|
try {
|
|
@@ -378,7 +377,7 @@ export async function compactFocusTreePlanAsync(plan, options = {}) {
|
|
|
378
377
|
let fallback;
|
|
379
378
|
let exhausted;
|
|
380
379
|
candidateSearch: for (const scale of compactScales(plan.focuses.length)) {
|
|
381
|
-
for (const compressRows of
|
|
380
|
+
for (const compressRows of [false, true]) {
|
|
382
381
|
options.signal?.throwIfAborted();
|
|
383
382
|
const candidate = compactCandidate(plan, currentLayout, scale, compressRows);
|
|
384
383
|
let layout;
|
|
@@ -425,7 +424,7 @@ export function assertCompactLayoutQuality(current, proposed) {
|
|
|
425
424
|
throw new ServiceError('FOCUS_COMPACT_QUALITY_BLOCKED', 'Compact focus reflow failed the absolute or relative layout-quality gate', {
|
|
426
425
|
treeId: proposed.treeId,
|
|
427
426
|
regressions,
|
|
428
|
-
limits: compactLimits(proposed.nodes.length
|
|
427
|
+
limits: compactLimits(proposed.nodes.length),
|
|
429
428
|
...(current === undefined ? {} : { before: requiredMetrics(current) }),
|
|
430
429
|
proposed: requiredMetrics(proposed),
|
|
431
430
|
});
|
|
@@ -1620,6 +1620,76 @@ function* connectorLengthDiagnostics(context, edges) {
|
|
|
1620
1620
|
});
|
|
1621
1621
|
}
|
|
1622
1622
|
}
|
|
1623
|
+
function* fakeComplexityDiagnostics(context, edges) {
|
|
1624
|
+
const incomingCount = new Map();
|
|
1625
|
+
const outgoingCount = new Map();
|
|
1626
|
+
for (const edge of edges) {
|
|
1627
|
+
incomingCount.set(edge.childId, (incomingCount.get(edge.childId) ?? 0) + 1);
|
|
1628
|
+
outgoingCount.set(edge.parentId, (outgoingCount.get(edge.parentId) ?? 0) + 1);
|
|
1629
|
+
}
|
|
1630
|
+
const linearEdges = edges.filter(({ parentId, childId }) => (outgoingCount.get(parentId) ?? 0) === 1 && (incomingCount.get(childId) ?? 0) === 1);
|
|
1631
|
+
const next = new Map(linearEdges.map((edge) => [edge.parentId, edge]));
|
|
1632
|
+
const linearChildren = new Set(linearEdges.map(({ childId }) => childId));
|
|
1633
|
+
for (const [edgeIndex, edge] of linearEdges.entries()) {
|
|
1634
|
+
yield* cancellationCheckpoint(context.signal, edgeIndex, 32);
|
|
1635
|
+
const spans = connectorSpans(edge);
|
|
1636
|
+
if (spans.horizontal === 0 && spans.vertical === 1)
|
|
1637
|
+
continue;
|
|
1638
|
+
const focus = context.focuses.get(edge.childId);
|
|
1639
|
+
context.diagnostics.push({
|
|
1640
|
+
code: 'FOCUS_LAYOUT_LINEAR_DETOUR',
|
|
1641
|
+
severity: 'warning',
|
|
1642
|
+
category: 'layout',
|
|
1643
|
+
message: `Mechanically linear connector ${edge.parentId} -> ${edge.childId} uses an unnecessary visual detour`,
|
|
1644
|
+
...(focus?.sourceLocation === undefined ? {} : { location: focus.sourceLocation }),
|
|
1645
|
+
details: {
|
|
1646
|
+
parentId: edge.parentId,
|
|
1647
|
+
childId: edge.childId,
|
|
1648
|
+
horizontalSpan: spans.horizontal,
|
|
1649
|
+
verticalSpan: spans.vertical,
|
|
1650
|
+
expectedHorizontalSpan: 0,
|
|
1651
|
+
expectedVerticalSpan: 1,
|
|
1652
|
+
},
|
|
1653
|
+
});
|
|
1654
|
+
}
|
|
1655
|
+
const starts = linearEdges
|
|
1656
|
+
.filter(({ parentId }) => !linearChildren.has(parentId))
|
|
1657
|
+
.sort((left, right) => compareCodeUnits(left.parentId, right.parentId));
|
|
1658
|
+
for (const start of starts) {
|
|
1659
|
+
const chain = [];
|
|
1660
|
+
const visited = new Set();
|
|
1661
|
+
let current = start;
|
|
1662
|
+
while (current !== undefined && !visited.has(current.parentId)) {
|
|
1663
|
+
visited.add(current.parentId);
|
|
1664
|
+
chain.push(current);
|
|
1665
|
+
current = next.get(current.childId);
|
|
1666
|
+
}
|
|
1667
|
+
const horizontalDirections = chain
|
|
1668
|
+
.map(({ parent, child }) => Math.sign(child.x - parent.x))
|
|
1669
|
+
.filter((direction) => direction !== 0);
|
|
1670
|
+
if (horizontalDirections.length < 2)
|
|
1671
|
+
continue;
|
|
1672
|
+
const sameDirection = horizontalDirections.every((direction) => direction === horizontalDirections[0]);
|
|
1673
|
+
const alternating = horizontalDirections.every((direction, index) => index === 0 || direction === -horizontalDirections[index - 1]);
|
|
1674
|
+
const code = sameDirection
|
|
1675
|
+
? 'FOCUS_LAYOUT_STAIRCASE_CHAIN'
|
|
1676
|
+
: alternating
|
|
1677
|
+
? 'FOCUS_LAYOUT_ZIGZAG_CHAIN'
|
|
1678
|
+
: undefined;
|
|
1679
|
+
if (code === undefined)
|
|
1680
|
+
continue;
|
|
1681
|
+
const focusIds = [chain[0].parentId, ...chain.map(({ childId }) => childId)];
|
|
1682
|
+
const focus = context.focuses.get(focusIds.at(-1) ?? '');
|
|
1683
|
+
context.diagnostics.push({
|
|
1684
|
+
code,
|
|
1685
|
+
severity: 'warning',
|
|
1686
|
+
category: 'layout',
|
|
1687
|
+
message: `${sameDirection ? 'Staircase' : 'Zigzag'} geometry makes the linear chain ${focusIds.join(' -> ')} look artificially complex`,
|
|
1688
|
+
...(focus?.sourceLocation === undefined ? {} : { location: focus.sourceLocation }),
|
|
1689
|
+
details: { focusIds, horizontalDirections },
|
|
1690
|
+
});
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1623
1693
|
function siblingCohortAnchor(context, cohort) {
|
|
1624
1694
|
const focus = context.focuses.get(cohort[0] ?? '');
|
|
1625
1695
|
const coordinates = cohort
|
|
@@ -1917,6 +1987,7 @@ function* layoutFocusTreeSteps(plan, options = {}) {
|
|
|
1917
1987
|
const nodeIntersectionCount = yield* connectorNodeIntersectionDiagnostics(context, edges);
|
|
1918
1988
|
yield* connectorCrossingDiagnostics(context, crossingSummary.samples);
|
|
1919
1989
|
yield* connectorLengthDiagnostics(context, edges);
|
|
1990
|
+
yield* fakeComplexityDiagnostics(context, edges);
|
|
1920
1991
|
const symmetry = yield* siblingSymmetryDiagnostics(context);
|
|
1921
1992
|
const nodes = [...context.placed.values()].sort((left, right) => compareCodeUnits(left.id, right.id));
|
|
1922
1993
|
const decisions = [...context.decisions].sort((left, right) => compareCodeUnits(left.focusId, right.focusId));
|
|
@@ -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 = '2.3.
|
|
3
|
+
export const PACKAGE_VERSION = '2.3.11';
|
|
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/focus.md
CHANGED
|
@@ -30,7 +30,7 @@ For a layout-only cleanup of an existing national tree, call `hoi4.focus_rewrite
|
|
|
30
30
|
|
|
31
31
|
Compact mode imports the tree, resets authored presentation coordinates and lane bounds, and performs a deterministic reflow in the same rewrite call. It keeps prerequisites, mutual exclusions, availability, bypasses, rewards, icons, localisation, AI behavior, and route/lane membership unchanged.
|
|
32
32
|
|
|
33
|
-
The rewrite measures canvas bounds, same-row spacing, the same curved connector paths used by the renderer, connector lengths, connector-node intersections, branch balance, and
|
|
33
|
+
The rewrite measures canvas bounds, same-row spacing, the same curved connector paths used by the renderer, connector lengths, connector-node intersections, branch balance, overall centering, and topology-aware fake-complexity patterns. Compact mode straightens mechanically linear chains and refuses a result with overlapping or cramped focuses, rendered crossings, connectors through unrelated focuses, long connectors, asymmetric or off-anchor sibling groups, offset linear detours, staircase or zigzag chains, an off-center canvas, or size metrics outside absolute and source-relative limits.
|
|
34
34
|
|
|
35
35
|
Use the default `layoutMode: "authored"` with a complete plan when deliberately designing coordinates or changing gameplay. Set `layoutMode: "compact"` with a complete plan when creating a large automatically arranged tree. Inspect and render calls remain useful before or after either rewrite mode, but a separate plan is not required for compact cleanup.
|
|
36
36
|
|
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": "2.3.
|
|
4
|
+
"version": "2.3.11",
|
|
5
5
|
"description": "Analyze HOI4 events, tech trees, AI weights, and MTTH; build focus trees, GUIs, and maps.",
|
|
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/v2.3.
|
|
2
|
+
"$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v2.3.11/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/v2.3.
|
|
2
|
+
"$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v2.3.11/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/v2.3.
|
|
2
|
+
"$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v2.3.11/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/v2.3.
|
|
2
|
+
"$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v2.3.11/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/v2.3.
|
|
2
|
+
"$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v2.3.11/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/v2.3.
|
|
2
|
+
"$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v2.3.11/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/v2.3.
|
|
2
|
+
"$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v2.3.11/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/v2.3.
|
|
2
|
+
"$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v2.3.11/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/v2.3.
|
|
2
|
+
"$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v2.3.11/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/v2.3.
|
|
2
|
+
"$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v2.3.11/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/v2.3.
|
|
2
|
+
"$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v2.3.11/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/v2.3.
|
|
2
|
+
"$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v2.3.11/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/v2.3.
|
|
2
|
+
"$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v2.3.11/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/v2.3.
|
|
2
|
+
"$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v2.3.11/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/v2.3.
|
|
2
|
+
"$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v2.3.11/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/v2.3.
|
|
2
|
+
"$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v2.3.11/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/v2.3.
|
|
2
|
+
"$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v2.3.11/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/v2.3.
|
|
2
|
+
"$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v2.3.11/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/v2.3.
|
|
2
|
+
"$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v2.3.11/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/v2.3.
|
|
2
|
+
"$id": "https://github.com/klimPaskov/hoi4-agent-tools/blob/v2.3.11/schemas/probability-sweep-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": "Analyze HOI4 events, tech trees, AI weights, and MTTH; build focus trees, GUIs, and maps.",
|
|
6
|
-
"version": "2.3.
|
|
6
|
+
"version": "2.3.11",
|
|
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": "2.3.
|
|
16
|
+
"version": "2.3.11",
|
|
17
17
|
"transport": {
|
|
18
18
|
"type": "stdio"
|
|
19
19
|
}
|