hoi4-agent-tools 3.9.0 → 4.0.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.
- package/CHANGELOG.md +118 -0
- package/README.md +115 -147
- package/dist/bin/http.js +12 -0
- package/dist/bin/setup.js +3 -2
- package/dist/bin/stdio.js +12 -0
- package/dist/hoi4_agent_tools/core/artifacts.js +40 -5
- package/dist/hoi4_agent_tools/core/canonical.js +18 -4
- package/dist/hoi4_agent_tools/core/configuration.js +7 -0
- package/dist/hoi4_agent_tools/core/domain-scan-patterns.js +12 -0
- package/dist/hoi4_agent_tools/core/domain-tools.js +65 -0
- package/dist/hoi4_agent_tools/core/domain-validation.js +5 -2
- package/dist/hoi4_agent_tools/core/engine.js +56 -10
- package/dist/hoi4_agent_tools/core/index.js +45 -20
- package/dist/hoi4_agent_tools/core/job-executor.js +14 -1
- package/dist/hoi4_agent_tools/core/job-operation-registration.js +15 -7
- package/dist/hoi4_agent_tools/core/job-store.js +78 -5
- package/dist/hoi4_agent_tools/core/job-transactions.js +31 -2
- package/dist/hoi4_agent_tools/core/job-worker-host.js +215 -116
- package/dist/hoi4_agent_tools/core/job-worker.js +90 -36
- package/dist/hoi4_agent_tools/core/operation-result.js +123 -10
- package/dist/hoi4_agent_tools/core/operation-tasks.js +49 -89
- package/dist/hoi4_agent_tools/core/persistent-analysis-cache.js +25 -21
- package/dist/hoi4_agent_tools/core/server-registry.js +155 -0
- package/dist/hoi4_agent_tools/core/server-status-resource.js +22 -0
- package/dist/hoi4_agent_tools/core/shared-request-capacity.js +26 -1
- package/dist/hoi4_agent_tools/core/source/cache.js +108 -29
- package/dist/hoi4_agent_tools/core/source/lexer.js +11 -3
- package/dist/hoi4_agent_tools/core/transactions.js +114 -23
- package/dist/hoi4_agent_tools/core/workspace.js +84 -8
- package/dist/hoi4_agent_tools/decision/ai.js +1 -1
- package/dist/hoi4_agent_tools/decision/service.js +28 -0
- package/dist/hoi4_agent_tools/decision/source-inventory.js +7 -5
- package/dist/hoi4_agent_tools/event/job-operations.js +9 -5
- package/dist/hoi4_agent_tools/event/operations.js +14 -1
- package/dist/hoi4_agent_tools/event/service.js +7 -0
- package/dist/hoi4_agent_tools/focus/job-operations.js +1 -2
- package/dist/hoi4_agent_tools/focus/tool-operations.js +1 -1
- package/dist/hoi4_agent_tools/gui/scenario-generator.js +11 -3
- package/dist/hoi4_agent_tools/gui/studio.js +20 -7
- package/dist/hoi4_agent_tools/gui/validators.js +8 -6
- package/dist/hoi4_agent_tools/map/bmp.js +1 -1
- package/dist/hoi4_agent_tools/map/derived.js +748 -0
- package/dist/hoi4_agent_tools/map/job-operations.js +7 -3
- package/dist/hoi4_agent_tools/map/model.js +103 -0
- package/dist/hoi4_agent_tools/map/operations.js +427 -58
- package/dist/hoi4_agent_tools/map/references.js +483 -0
- package/dist/hoi4_agent_tools/map/service.js +136 -61
- package/dist/hoi4_agent_tools/map/tool-operations.js +2 -1
- package/dist/hoi4_agent_tools/map/validation.js +3 -0
- package/dist/hoi4_agent_tools/map/world.js +1280 -0
- package/dist/hoi4_agent_tools/mcp/resources/register-modern.js +13 -1
- package/dist/hoi4_agent_tools/mcp/resources/register.js +6 -0
- package/dist/hoi4_agent_tools/mcp/server/argument-errors.js +72 -0
- package/dist/hoi4_agent_tools/mcp/server/create-modern-operations.js +23 -5
- package/dist/hoi4_agent_tools/mcp/server/create.js +7 -0
- package/dist/hoi4_agent_tools/mcp/server/request-lifecycle.js +24 -30
- package/dist/hoi4_agent_tools/mcp/server/tool-listing.js +45 -0
- package/dist/hoi4_agent_tools/mcp/tools/analysis.js +25 -5
- package/dist/hoi4_agent_tools/mcp/tools/event.js +18 -29
- package/dist/hoi4_agent_tools/mcp/tools/focus.js +4 -12
- package/dist/hoi4_agent_tools/mcp/tools/gui.js +3 -3
- package/dist/hoi4_agent_tools/mcp/tools/job.js +2 -2
- package/dist/hoi4_agent_tools/mcp/tools/map.js +13 -16
- package/dist/hoi4_agent_tools/mcp/tools/probability.js +42 -48
- package/dist/hoi4_agent_tools/mcp/tools/reference.js +22 -5
- package/dist/hoi4_agent_tools/mcp/tools/technology.js +16 -26
- package/dist/hoi4_agent_tools/mcp/transports/http.js +28 -4
- package/dist/hoi4_agent_tools/mcp/transports/stdio-lifetime.js +37 -18
- package/dist/hoi4_agent_tools/probability/job-operations.js +4 -9
- package/dist/hoi4_agent_tools/probability/operations.js +175 -13
- package/dist/hoi4_agent_tools/probability/source-analysis.js +24 -1
- package/dist/hoi4_agent_tools/reference/error-log.js +359 -0
- package/dist/hoi4_agent_tools/reference/known-mistakes.js +307 -0
- package/dist/hoi4_agent_tools/reference/known-mistakes.json +154 -0
- package/dist/hoi4_agent_tools/reference/mod-index.js +101 -0
- package/dist/hoi4_agent_tools/reference/operations.js +88 -19
- package/dist/hoi4_agent_tools/reference/player-text.js +4 -3
- package/dist/hoi4_agent_tools/reference/script-validation.js +19 -1
- package/dist/hoi4_agent_tools/reference/service.js +6 -0
- package/dist/hoi4_agent_tools/schemas/event.js +78 -19
- package/dist/hoi4_agent_tools/schemas/focus-requests.js +10 -0
- package/dist/hoi4_agent_tools/schemas/lenient-arguments.js +266 -0
- package/dist/hoi4_agent_tools/schemas/map-requests.js +63 -20
- package/dist/hoi4_agent_tools/schemas/map.js +122 -3
- package/dist/hoi4_agent_tools/schemas/mod-tools.js +181 -0
- package/dist/hoi4_agent_tools/schemas/probability-requests.js +119 -9
- package/dist/hoi4_agent_tools/schemas/reference.js +13 -0
- package/dist/hoi4_agent_tools/schemas/scenarios.js +1 -3
- package/dist/hoi4_agent_tools/schemas/script-validation.js +13 -6
- package/dist/hoi4_agent_tools/schemas/technology.js +83 -23
- package/dist/hoi4_agent_tools/technology/job-operations.js +3 -4
- package/dist/hoi4_agent_tools/technology/operations.js +14 -1
- package/dist/hoi4_agent_tools/technology/service.js +7 -0
- package/dist/hoi4_agent_tools/version.js +1 -1
- package/docs/README.md +7 -4
- package/docs/analysis.md +13 -0
- package/docs/configuration.md +281 -0
- package/docs/development.md +24 -2
- package/docs/events.md +27 -3
- package/docs/examples.md +6 -6
- package/docs/focus.md +125 -4
- package/docs/gui.md +98 -17
- package/docs/helper-expansion.md +8 -8
- package/docs/http.md +3 -1
- package/docs/jobs.md +19 -13
- package/docs/map.md +197 -6
- package/docs/mechanics.md +4 -0
- package/docs/probability.md +42 -15
- package/docs/reference.md +71 -4
- package/docs/setup.md +45 -11
- package/docs/technology.md +26 -1
- package/docs/third-party-notices.md +11 -0
- package/docs/tools.md +151 -42
- package/docs/troubleshooting.md +61 -0
- package/examples/clients/codex-config.toml +5 -2
- package/examples/clients/generic.json +2 -2
- package/examples/config/config.json +7 -0
- package/npm-shrinkwrap.json +161 -162
- package/package.json +13 -8
- package/schemas/configuration.schema.json +144 -128
- package/schemas/continuous-focus-palette.schema.json +1 -1
- package/schemas/custom-weighted-pool.schema.json +1 -1
- package/schemas/decision-inspect-input.schema.json +1 -1
- package/schemas/error-log-input.schema.json +55 -0
- 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/helper-expansion-request.schema.json +1 -1
- package/schemas/helper-expansion-summary.schema.json +1 -1
- package/schemas/impact-inspect-input.schema.json +1 -1
- package/schemas/map-operation.schema.json +597 -126
- package/schemas/mechanic-test-input.schema.json +1 -1
- package/schemas/mod-index-input.schema.json +51 -0
- package/schemas/operation-result.schema.json +2 -2
- package/schemas/package-check-input.schema.json +1 -1
- package/schemas/package-manifest.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/schemas/reference-context-input.schema.json +1 -1
- package/schemas/reference-read-input.schema.json +1 -1
- package/schemas/reference-search-input.schema.json +1 -1
- package/schemas/scenario-suite.schema.json +3 -5
- package/schemas/scenario-test-input.schema.json +3 -5
- package/schemas/script-validate-input.schema.json +1 -1
- package/schemas/shared-scenario.schema.json +1 -1
- package/schemas/source-lookup-input.schema.json +1 -1
- package/server.json +3 -3
|
@@ -917,6 +917,8 @@ export function guiArtifactProvenance(graph, kind, primaryScene, scenarioScenes
|
|
|
917
917
|
};
|
|
918
918
|
}
|
|
919
919
|
const sharedGuiGraphs = new WeakMap();
|
|
920
|
+
/** Graphs kept per engine: one for each scope a preview builds, across a few workspaces. */
|
|
921
|
+
const GUI_GRAPH_CACHE_SCOPES = 6;
|
|
920
922
|
export class ScriptedGuiStudio {
|
|
921
923
|
engine;
|
|
922
924
|
resolver;
|
|
@@ -953,12 +955,21 @@ export class ScriptedGuiStudio {
|
|
|
953
955
|
return cached;
|
|
954
956
|
}
|
|
955
957
|
const retainedFiles = [...files];
|
|
958
|
+
// The previous graph of this scope still indexes every unchanged file.
|
|
959
|
+
const previous = [...this.#graphCache].find(([existing]) => existing.startsWith(`${scope}:`))?.[1].index;
|
|
960
|
+
const index = this.engine.indexFiles(retainedFiles, previous);
|
|
956
961
|
const scanned = {
|
|
957
962
|
files: retainedFiles,
|
|
958
|
-
graph: buildGuiSourceGraph(retainedFiles,
|
|
963
|
+
graph: buildGuiSourceGraph(retainedFiles, index, additionalLocalisationKeys),
|
|
964
|
+
index,
|
|
959
965
|
};
|
|
966
|
+
// One graph per scope: a preview builds layout, game-layout and definition graphs, and a
|
|
967
|
+
// single shared slot made each repeat call rebuild all of them.
|
|
968
|
+
for (const existing of this.#graphCache.keys())
|
|
969
|
+
if (existing.startsWith(`${scope}:`))
|
|
970
|
+
this.#graphCache.delete(existing);
|
|
960
971
|
this.#graphCache.set(key, scanned);
|
|
961
|
-
while (this.#graphCache.size >
|
|
972
|
+
while (this.#graphCache.size > GUI_GRAPH_CACHE_SCOPES) {
|
|
962
973
|
const oldest = this.#graphCache.keys().next().value;
|
|
963
974
|
if (oldest === undefined)
|
|
964
975
|
break;
|
|
@@ -1004,7 +1015,7 @@ export class ScriptedGuiStudio {
|
|
|
1004
1015
|
const gameGraph = this.graphForFiles(gameLayouts.files, `game-layout:${workspaceId}`).graph;
|
|
1005
1016
|
const selectedPaths = new Set(selectedElements(gameGraph, windowName, [...requiredNames]).map(({ sourcePath }) => sourcePath));
|
|
1006
1017
|
layoutFiles = mergeScannedFiles(layoutFiles, gameLayouts.files.filter(({ displayPath }) => selectedPaths.has(displayPath)));
|
|
1007
|
-
layoutGraph = this.graphForFiles(layoutFiles, `layout:${workspaceId}`).graph;
|
|
1018
|
+
layoutGraph = this.graphForFiles(layoutFiles, `merged-layout:${workspaceId}`).graph;
|
|
1008
1019
|
}
|
|
1009
1020
|
if (!layoutGraph.elements.some(({ name }) => name === windowName))
|
|
1010
1021
|
assertTargetWindowAvailable(layoutGraph, windowName);
|
|
@@ -1062,12 +1073,13 @@ export class ScriptedGuiStudio {
|
|
|
1062
1073
|
? undefined
|
|
1063
1074
|
: parseGeneratedScenarioOptions(input.generatedScenarios);
|
|
1064
1075
|
const scanned = await this.scanWindow(input.workspaceId, input.windowName, input.principal, input.signal, [placeholderScenario.language, ...explicitRelatedScenarios.map(({ language }) => language)], scenarioSpriteNames([placeholderScenario, ...explicitRelatedScenarios], generatedOptions?.textSamples), scenarioTemplateNames([placeholderScenario, ...explicitRelatedScenarios]), scenarioCountryFlagPatterns([placeholderScenario, ...explicitRelatedScenarios]), scenarioLocalisationKeys([placeholderScenario, ...explicitRelatedScenarios]), [placeholderScenario, ...explicitRelatedScenarios].some(({ tooltip }) => tooltip !== undefined));
|
|
1065
|
-
|
|
1076
|
+
let builtDefinitions;
|
|
1077
|
+
const evaluationDefinitions = () => (builtDefinitions ??= ClausewitzEvaluationDefinitions.build(scanned));
|
|
1066
1078
|
const resolveLocalisation = (target) => resolveScenarioScriptedLocalisation(scanned.graph, input.windowName, target, evaluationDefinitions);
|
|
1067
1079
|
const suppliedScenario = resolveLocalisation(placeholderScenario);
|
|
1068
1080
|
const generatedScenarios = generatedOptions === undefined
|
|
1069
1081
|
? []
|
|
1070
|
-
: generateGuiPreviewScenarios(scanned.graph, input.windowName, placeholderScenario, generatedOptions, evaluationDefinitions);
|
|
1082
|
+
: generateGuiPreviewScenarios(scanned.graph, input.windowName, placeholderScenario, generatedOptions, evaluationDefinitions());
|
|
1071
1083
|
const scenario = generatedScenarios[0] ?? suppliedScenario;
|
|
1072
1084
|
const relatedScenarios = [
|
|
1073
1085
|
...(generatedOptions?.preservePlaceholder === true && generatedScenarios.length > 0
|
|
@@ -1160,12 +1172,13 @@ export class ScriptedGuiStudio {
|
|
|
1160
1172
|
...(requestedBaselineScenario === undefined ? [] : [requestedBaselineScenario]),
|
|
1161
1173
|
...explicitRelatedScenarios,
|
|
1162
1174
|
].some(({ tooltip }) => tooltip !== undefined));
|
|
1163
|
-
|
|
1175
|
+
let builtDefinitions;
|
|
1176
|
+
const evaluationDefinitions = () => (builtDefinitions ??= ClausewitzEvaluationDefinitions.build(scanned));
|
|
1164
1177
|
const resolveLocalisation = (target) => resolveScenarioScriptedLocalisation(scanned.graph, input.windowName, target, evaluationDefinitions);
|
|
1165
1178
|
const suppliedScenario = resolveLocalisation(placeholderScenario);
|
|
1166
1179
|
const generatedScenarios = generatedOptions === undefined
|
|
1167
1180
|
? []
|
|
1168
|
-
: generateGuiPreviewScenarios(scanned.graph, input.windowName, placeholderScenario, generatedOptions, evaluationDefinitions);
|
|
1181
|
+
: generateGuiPreviewScenarios(scanned.graph, input.windowName, placeholderScenario, generatedOptions, evaluationDefinitions());
|
|
1169
1182
|
const scenario = generatedScenarios[0] ?? suppliedScenario;
|
|
1170
1183
|
const relatedScenarios = [
|
|
1171
1184
|
...(generatedOptions?.preservePlaceholder === true && generatedScenarios.length > 0
|
|
@@ -490,15 +490,17 @@ function validateOverlapAndGeometry(scene, diagnostics, work) {
|
|
|
490
490
|
if (overlap === undefined)
|
|
491
491
|
continue;
|
|
492
492
|
const ratio = area(overlap) / Math.max(1, Math.min(area(left.rect), area(right.rect)));
|
|
493
|
+
// Tab pages and alternative panels overlap by design; the game shows one at a time.
|
|
494
|
+
// When the scenario cannot decide which, the preview draws them stacked, and the pair
|
|
495
|
+
// is reported only as missing scenario facts, not as a layout or click conflict.
|
|
496
|
+
if (left.visibilityStatus === 'unresolved' || right.visibilityStatus === 'unresolved') {
|
|
497
|
+
if (left.depth === right.depth && ratio > 0.2)
|
|
498
|
+
diagnostics.push(issue('GUI_UNRESOLVED_VISIBILITY_OVERLAP', 'warning', 'layout', `${left.name} and ${right.name} overlap and the scenario does not decide which is visible, so the preview draws both. Declare the flags or variables their visible triggers read, with closedFlags, to render one of them.`, right, { left: left.id, right: right.id, ratio }));
|
|
499
|
+
continue;
|
|
500
|
+
}
|
|
493
501
|
if (left.clickable && right.clickable && ratio > 0.02) {
|
|
494
502
|
diagnostics.push(issue('GUI_CONFLICTING_CLICK_REGIONS', 'error', 'design', `${left.name} and ${right.name} have overlapping click regions (${(ratio * 100).toFixed(1)}%).`, right, { left: left.id, right: right.id, ratio }));
|
|
495
503
|
}
|
|
496
|
-
// Tab pages and alternative panels overlap by design; the game shows one at a time.
|
|
497
|
-
// When the scenario cannot decide which, the preview draws them stacked.
|
|
498
|
-
if (left.depth === right.depth &&
|
|
499
|
-
ratio > 0.2 &&
|
|
500
|
-
(left.visibilityStatus === 'unresolved' || right.visibilityStatus === 'unresolved'))
|
|
501
|
-
diagnostics.push(issue('GUI_UNRESOLVED_VISIBILITY_OVERLAP', 'warning', 'layout', `${left.name} and ${right.name} overlap and the scenario does not decide which is visible, so the preview draws both. Declare the flags or variables their visible triggers read, with closedFlags, to render one of them.`, right, { left: left.id, right: right.id, ratio }));
|
|
502
504
|
if (left.depth === right.depth && ratio > 0.2) {
|
|
503
505
|
diagnostics.push(issue('GUI_VISIBLE_OVERLAP', 'warning', 'layout', `${left.name} and ${right.name} overlap by ${(ratio * 100).toFixed(1)}% of the smaller element.`, right, { left: left.id, right: right.id, ratio }));
|
|
504
506
|
}
|
|
@@ -314,7 +314,7 @@ export function createBmp(options) {
|
|
|
314
314
|
bytes.writeUInt32LE(0, 30);
|
|
315
315
|
bytes.writeUInt32LE(stride * options.height, 34);
|
|
316
316
|
if (options.bitsPerPixel === 8)
|
|
317
|
-
bytes.writeUInt32LE(
|
|
317
|
+
bytes.writeUInt32LE(options.colorsUsed ?? palette.length, 46);
|
|
318
318
|
for (const [index, color] of palette.entries()) {
|
|
319
319
|
const offset = 14 + dibSize + index * 4;
|
|
320
320
|
bytes[offset] = color.b;
|