hoi4-agent-tools 3.10.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 +109 -0
- package/README.md +115 -147
- package/dist/bin/http.js +10 -0
- package/dist/bin/setup.js +3 -2
- package/dist/bin/stdio.js +10 -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 +29 -2
- package/dist/hoi4_agent_tools/core/index.js +2 -2
- 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 +22 -5
- package/dist/hoi4_agent_tools/core/shared-request-capacity.js +26 -1
- package/dist/hoi4_agent_tools/core/source/cache.js +20 -10
- 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/focus/job-operations.js +1 -2
- package/dist/hoi4_agent_tools/focus/tool-operations.js +1 -1
- 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/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 -29
- package/dist/hoi4_agent_tools/mcp/transports/http.js +28 -4
- package/dist/hoi4_agent_tools/mcp/transports/stdio-lifetime.js +31 -8
- 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 +79 -21
- 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/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 +44 -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 +151 -156
- 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
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { MAP_REFERENCE_SCRIPT_PATTERNS, mapScriptConsistency } from './references.js';
|
|
1
2
|
import path from 'node:path';
|
|
2
3
|
import { escapeFileGlob } from '../core/file-glob.js';
|
|
3
4
|
import { ArtifactStore, boundedSourceHashEvidence, publicArtifactLink, } from '../core/artifacts.js';
|
|
@@ -381,6 +382,8 @@ function sourceTextPatterns(roots) {
|
|
|
381
382
|
return [
|
|
382
383
|
'common/bookmarks/**/*.txt',
|
|
383
384
|
'common/terrain/*.txt',
|
|
385
|
+
'common/buildings/*.txt',
|
|
386
|
+
'descriptor.mod',
|
|
384
387
|
...roots.map.flatMap((root) => {
|
|
385
388
|
const normalized = normalizeSourceRoot(root);
|
|
386
389
|
return ['map', 'csv', 'txt'].map((extension) => `${normalized}/**/*.${extension}`);
|
|
@@ -396,18 +399,24 @@ function provinceBitmapPatterns(defaultMaps, mapRoots) {
|
|
|
396
399
|
const activeByPath = new Map(defaultMaps
|
|
397
400
|
.filter(({ shadowedBy }) => shadowedBy === undefined)
|
|
398
401
|
.map((file) => [file.relativePath.replaceAll('\\', '/').toLowerCase(), file]));
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
activeName =
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
402
|
+
// The province bitmap, and the heightmap that gives generated positions their height.
|
|
403
|
+
const names = new Set();
|
|
404
|
+
for (const [selector, fallback] of [
|
|
405
|
+
['provinces', 'provinces.bmp'],
|
|
406
|
+
['heightmap', 'heightmap.bmp'],
|
|
407
|
+
]) {
|
|
408
|
+
let activeName = fallback;
|
|
409
|
+
for (const root of mapRoots) {
|
|
410
|
+
const relativePath = `${normalizeSourceRoot(root)}/default.map`.toLowerCase();
|
|
411
|
+
const active = activeByPath.get(relativePath);
|
|
412
|
+
if (active === undefined)
|
|
413
|
+
continue;
|
|
414
|
+
activeName = defaultMapSelectorValue(active, selector, activeName);
|
|
415
|
+
break;
|
|
416
|
+
}
|
|
417
|
+
names.add(activeName);
|
|
418
|
+
for (const file of defaultMaps)
|
|
419
|
+
names.add(defaultMapSelectorValue(file, selector, activeName));
|
|
411
420
|
}
|
|
412
421
|
const patterns = new Set();
|
|
413
422
|
for (const root of mapRoots) {
|
|
@@ -463,6 +472,43 @@ function validationWithPlan(validation, plan) {
|
|
|
463
472
|
checks,
|
|
464
473
|
};
|
|
465
474
|
}
|
|
475
|
+
/**
|
|
476
|
+
* A map whose bitmap changed size (a new world) cannot be diffed pixel by pixel; its review
|
|
477
|
+
* image is the whole proposed map, and every province counts as changed.
|
|
478
|
+
*/
|
|
479
|
+
async function wholeMapDiff(after, options) {
|
|
480
|
+
const rendered = await renderMap(after, {
|
|
481
|
+
layer: 'state',
|
|
482
|
+
overlays: ['coastlines', 'ports', 'victory-points', 'supply-nodes', 'railways'],
|
|
483
|
+
...(options?.scale === undefined ? {} : { scale: options.scale }),
|
|
484
|
+
...(options?.signal === undefined ? {} : { signal: options.signal }),
|
|
485
|
+
...(options?.budget === undefined ? {} : { budget: options.budget }),
|
|
486
|
+
});
|
|
487
|
+
return {
|
|
488
|
+
...rendered,
|
|
489
|
+
changedProvinceIds: after.definitions.map(({ id }) => id).filter((id) => id > 0),
|
|
490
|
+
semantic: {
|
|
491
|
+
definitions: [],
|
|
492
|
+
stateMembership: [],
|
|
493
|
+
regionMembership: [],
|
|
494
|
+
states: [],
|
|
495
|
+
ports: [],
|
|
496
|
+
buildingPositions: [],
|
|
497
|
+
unitPositions: [],
|
|
498
|
+
weatherPositions: [],
|
|
499
|
+
entityLocators: [],
|
|
500
|
+
supplyNodes: [],
|
|
501
|
+
railways: [],
|
|
502
|
+
adjacencies: [],
|
|
503
|
+
normalAdjacencies: [],
|
|
504
|
+
supplyNodesChanged: true,
|
|
505
|
+
railwaysChanged: true,
|
|
506
|
+
adjacenciesChanged: true,
|
|
507
|
+
normalAdjacenciesChanged: true,
|
|
508
|
+
},
|
|
509
|
+
...(options?.review === undefined ? {} : { review: options.review }),
|
|
510
|
+
};
|
|
511
|
+
}
|
|
466
512
|
export class AgentNudger {
|
|
467
513
|
engine;
|
|
468
514
|
resolver;
|
|
@@ -497,17 +543,7 @@ export class AgentNudger {
|
|
|
497
543
|
const locatorSnapshot = await this.engine.scan(workspaceId, { patterns: ['**/*.asset'], rootKinds: ['mod', 'fixture'] }, principal, signal);
|
|
498
544
|
const externalScriptSnapshot = includeExternalScriptReferences
|
|
499
545
|
? await this.engine.scan(workspaceId, {
|
|
500
|
-
patterns: [
|
|
501
|
-
'events/**/*.txt',
|
|
502
|
-
'common/national_focus/**/*.txt',
|
|
503
|
-
'common/decisions/**/*.txt',
|
|
504
|
-
'common/scripted_effects/**/*.txt',
|
|
505
|
-
'common/scripted_triggers/**/*.txt',
|
|
506
|
-
'common/on_actions/**/*.txt',
|
|
507
|
-
'common/ideas/**/*.txt',
|
|
508
|
-
'common/characters/**/*.txt',
|
|
509
|
-
'history/countries/**/*.txt',
|
|
510
|
-
],
|
|
546
|
+
patterns: [...MAP_REFERENCE_SCRIPT_PATTERNS],
|
|
511
547
|
}, principal, signal)
|
|
512
548
|
: undefined;
|
|
513
549
|
signal?.throwIfAborted();
|
|
@@ -524,20 +560,43 @@ export class AgentNudger {
|
|
|
524
560
|
index: MapWorkspaceIndex.build(files, sourceRoots, SymbolIndex.build(files)),
|
|
525
561
|
};
|
|
526
562
|
}
|
|
527
|
-
async validate(workspaceId, principal, signal) {
|
|
528
|
-
const snapshot = await this.scan(workspaceId, principal, signal);
|
|
563
|
+
async validate(workspaceId, principal, signal, scripts = false) {
|
|
564
|
+
const snapshot = await this.scan(workspaceId, principal, signal, scripts);
|
|
565
|
+
const validation = await validateMapAsync(snapshot.index, signal === undefined ? {} : { signal });
|
|
566
|
+
if (!scripts)
|
|
567
|
+
return { snapshot, validation };
|
|
568
|
+
const consistency = mapScriptConsistency(snapshot.index);
|
|
569
|
+
const diagnostics = sortDiagnostics([...validation.diagnostics, ...consistency.diagnostics]);
|
|
529
570
|
return {
|
|
530
571
|
snapshot,
|
|
531
|
-
validation:
|
|
572
|
+
validation: {
|
|
573
|
+
...validation,
|
|
574
|
+
passed: validation.passed &&
|
|
575
|
+
!consistency.diagnostics.some(({ severity }) => severity === 'error'),
|
|
576
|
+
diagnostics,
|
|
577
|
+
checks: [
|
|
578
|
+
...validation.checks,
|
|
579
|
+
{
|
|
580
|
+
id: 'map-script-references',
|
|
581
|
+
passed: consistency.missing === 0,
|
|
582
|
+
message: `${consistency.references} script reference(s) to map entities checked; ${consistency.missing} name an undefined state, province or region`,
|
|
583
|
+
},
|
|
584
|
+
],
|
|
585
|
+
},
|
|
586
|
+
scriptReferences: { references: consistency.references, missing: consistency.missing },
|
|
532
587
|
};
|
|
533
588
|
}
|
|
534
589
|
async prepareOperations(workspaceId, operations, principal, signal) {
|
|
535
590
|
signal?.throwIfAborted();
|
|
536
|
-
const snapshot = await this.scan(workspaceId, principal, signal, operations.some((
|
|
591
|
+
const snapshot = await this.scan(workspaceId, principal, signal, operations.some((operation) => operation.kind === 'renumber_map_entity' ||
|
|
592
|
+
operation.kind === 'remap_map_references' ||
|
|
593
|
+
'remapReferences' in operation));
|
|
537
594
|
const plan = await planMapOperationsAsync(snapshot.index, operations, signal);
|
|
538
595
|
const baselineValidation = await validateMapAsync(snapshot.index, signal === undefined ? {} : { signal });
|
|
596
|
+
// A new world has nothing to compare its bitmap format and pixels with.
|
|
597
|
+
const newWorld = operations.some(({ kind }) => kind === 'create_world');
|
|
539
598
|
const rawValidation = await validateMapAsync(plan.finalIndex, {
|
|
540
|
-
baseline: snapshot.index,
|
|
599
|
+
...(newWorld ? {} : { baseline: snapshot.index }),
|
|
541
600
|
...(signal === undefined ? {} : { signal }),
|
|
542
601
|
...(plan.expectedChangedBounds === undefined
|
|
543
602
|
? {}
|
|
@@ -739,20 +798,35 @@ export class AgentNudger {
|
|
|
739
798
|
'victory-points',
|
|
740
799
|
'weather-positions',
|
|
741
800
|
];
|
|
801
|
+
const hasBeforeMap = snapshot.index.raster !== undefined ||
|
|
802
|
+
snapshot.index.diagnostics.some(({ code }) => code.startsWith('RENDER_'));
|
|
803
|
+
const sameSize = snapshot.index.provinceBitmap !== undefined &&
|
|
804
|
+
snapshot.index.provinceBitmap.width === plan.finalIndex.provinceBitmap?.width &&
|
|
805
|
+
snapshot.index.provinceBitmap.height === plan.finalIndex.provinceBitmap.height;
|
|
742
806
|
const [rawBundle, rawBeforeBundle, rawProposedBundle] = await Promise.all([
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
807
|
+
sameSize
|
|
808
|
+
? renderMapDiff(snapshot.index, plan.finalIndex, {
|
|
809
|
+
...(options.scale === undefined ? {} : { scale: options.scale }),
|
|
810
|
+
...(options.signal === undefined ? {} : { signal: options.signal }),
|
|
811
|
+
budget,
|
|
812
|
+
review,
|
|
813
|
+
})
|
|
814
|
+
: wholeMapDiff(plan.finalIndex, {
|
|
815
|
+
...(options.scale === undefined ? {} : { scale: options.scale }),
|
|
816
|
+
...(options.signal === undefined ? {} : { signal: options.signal }),
|
|
817
|
+
budget,
|
|
818
|
+
review,
|
|
819
|
+
}),
|
|
820
|
+
// A new world over a game without any map has nothing to draw as "before".
|
|
821
|
+
hasBeforeMap
|
|
822
|
+
? renderMap(snapshot.index, {
|
|
823
|
+
layer: 'state',
|
|
824
|
+
overlays: [...comparisonOverlays],
|
|
825
|
+
...(options.scale === undefined ? {} : { scale: options.scale }),
|
|
826
|
+
...(options.signal === undefined ? {} : { signal: options.signal }),
|
|
827
|
+
budget,
|
|
828
|
+
})
|
|
829
|
+
: Promise.resolve(undefined),
|
|
756
830
|
renderMap(plan.finalIndex, {
|
|
757
831
|
layer: 'state',
|
|
758
832
|
overlays: [...comparisonOverlays],
|
|
@@ -764,7 +838,9 @@ export class AgentNudger {
|
|
|
764
838
|
const completeSourceHashes = sourceHashes(snapshot);
|
|
765
839
|
const sourceEvidence = boundedSourceHashEvidence(completeSourceHashes);
|
|
766
840
|
const bundle = mapBundleWithSourceHashes(rawBundle, completeSourceHashes);
|
|
767
|
-
const beforeBundle =
|
|
841
|
+
const beforeBundle = rawBeforeBundle === undefined
|
|
842
|
+
? undefined
|
|
843
|
+
: mapBundleWithSourceHashes(rawBeforeBundle, completeSourceHashes);
|
|
768
844
|
const proposedBundle = mapBundleWithSourceHashes(rawProposedBundle, completeSourceHashes);
|
|
769
845
|
const workspace = this.resolver.get(snapshot.workspaceId, options.principal);
|
|
770
846
|
const provenance = {
|
|
@@ -816,24 +892,6 @@ export class AgentNudger {
|
|
|
816
892
|
content: bundle.html,
|
|
817
893
|
provenance,
|
|
818
894
|
},
|
|
819
|
-
{
|
|
820
|
-
name: 'map-before.png',
|
|
821
|
-
mimeType: 'image/png',
|
|
822
|
-
content: beforeBundle.png,
|
|
823
|
-
provenance: comparisonProvenance('before'),
|
|
824
|
-
},
|
|
825
|
-
{
|
|
826
|
-
name: 'map-before.json',
|
|
827
|
-
mimeType: 'application/json',
|
|
828
|
-
content: beforeBundle.json,
|
|
829
|
-
provenance: comparisonProvenance('before'),
|
|
830
|
-
},
|
|
831
|
-
{
|
|
832
|
-
name: 'map-before.html',
|
|
833
|
-
mimeType: 'text/html',
|
|
834
|
-
content: beforeBundle.html,
|
|
835
|
-
provenance: comparisonProvenance('before'),
|
|
836
|
-
},
|
|
837
895
|
{
|
|
838
896
|
name: 'map-proposed.png',
|
|
839
897
|
mimeType: 'image/png',
|
|
@@ -853,10 +911,27 @@ export class AgentNudger {
|
|
|
853
911
|
provenance: comparisonProvenance('proposed'),
|
|
854
912
|
},
|
|
855
913
|
];
|
|
914
|
+
if (beforeBundle !== undefined)
|
|
915
|
+
writes.splice(3, 0, {
|
|
916
|
+
name: 'map-before.png',
|
|
917
|
+
mimeType: 'image/png',
|
|
918
|
+
content: beforeBundle.png,
|
|
919
|
+
provenance: comparisonProvenance('before'),
|
|
920
|
+
}, {
|
|
921
|
+
name: 'map-before.json',
|
|
922
|
+
mimeType: 'application/json',
|
|
923
|
+
content: beforeBundle.json,
|
|
924
|
+
provenance: comparisonProvenance('before'),
|
|
925
|
+
}, {
|
|
926
|
+
name: 'map-before.html',
|
|
927
|
+
mimeType: 'text/html',
|
|
928
|
+
content: beforeBundle.html,
|
|
929
|
+
provenance: comparisonProvenance('before'),
|
|
930
|
+
});
|
|
856
931
|
const artifacts = await this.artifacts.withAtomicChunkedWrites(workspace, writes, (stored) => Promise.resolve([...stored]), options.signal);
|
|
857
932
|
return {
|
|
858
933
|
bundle,
|
|
859
|
-
beforeBundle,
|
|
934
|
+
...(beforeBundle === undefined ? {} : { beforeBundle }),
|
|
860
935
|
proposedBundle,
|
|
861
936
|
plan,
|
|
862
937
|
artifacts,
|
|
@@ -362,7 +362,7 @@ export async function inspectMap(engine, nudger, input, context) {
|
|
|
362
362
|
await context.progress(3, 3, 'Map lookup complete');
|
|
363
363
|
return result;
|
|
364
364
|
}
|
|
365
|
-
const { snapshot, validation } = await nudger.validate(context.workspaceId, context.principal, context.signal);
|
|
365
|
+
const { snapshot, validation, scriptReferences } = await nudger.validate(context.workspaceId, context.principal, context.signal, input.references);
|
|
366
366
|
const sharedRevision = snapshot.revision;
|
|
367
367
|
const catalog = buildMapCatalog(snapshot.index);
|
|
368
368
|
const queryMatches = input.query === undefined ? [] : searchMapCatalog(catalog, input.query, input.queryLimit);
|
|
@@ -522,6 +522,7 @@ export async function inspectMap(engine, nudger, input, context) {
|
|
|
522
522
|
provinceGeometryRowRunCount: provinceGeometry?.rowRunCount ?? 0,
|
|
523
523
|
unknownProvinceIds: provinceGeometry?.unknownProvinceIds ?? [],
|
|
524
524
|
missingGeometryProvinceIds: provinceGeometry?.missingGeometryProvinceIds ?? [],
|
|
525
|
+
...(scriptReferences === undefined ? {} : { scriptReferences }),
|
|
525
526
|
});
|
|
526
527
|
result.code = 'MAP_INSPECTED';
|
|
527
528
|
setInlineFilesScanned(result, snapshot.files.map(({ displayPath }) => displayPath));
|
|
@@ -546,6 +546,9 @@ function* validateDefinitions(index, diagnostics, options) {
|
|
|
546
546
|
}
|
|
547
547
|
for (const [definitionIndex, definition] of index.definitions.entries()) {
|
|
548
548
|
yield* cancellationCheckpoint(options.signal, definitionIndex, 256);
|
|
549
|
+
// Province 0 is the reserved null row (0;0;0;0;land;false;unknown;0) the game expects.
|
|
550
|
+
if (definition.id === 0 && definition.terrain === 'unknown')
|
|
551
|
+
continue;
|
|
549
552
|
const terrain = index.terrainCategories?.get(definition.terrain);
|
|
550
553
|
if (index.terrainCategories !== undefined && terrain === undefined) {
|
|
551
554
|
addDiagnostic(diagnostics, options, {
|