hoi4-agent-tools 0.1.7 → 1.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 +12 -94
- package/README.md +35 -121
- package/SECURITY.md +5 -5
- package/dist/bin/http.js +0 -1
- package/dist/bin/setup.js +141 -85
- package/dist/bin/stdio.js +0 -1
- package/dist/hoi4_agent_tools/core/artifacts.js +0 -1
- package/dist/hoi4_agent_tools/core/canonical.js +0 -1
- package/dist/hoi4_agent_tools/core/configuration.js +28 -28
- package/dist/hoi4_agent_tools/core/diagnostic-collector.js +0 -1
- package/dist/hoi4_agent_tools/core/diagnostics.js +0 -1
- package/dist/hoi4_agent_tools/core/diff.js +0 -1
- package/dist/hoi4_agent_tools/core/engine.js +6 -20
- package/dist/hoi4_agent_tools/core/image-diff.js +0 -1
- package/dist/hoi4_agent_tools/core/index.js +0 -1
- package/dist/hoi4_agent_tools/core/render-budget.js +0 -1
- package/dist/hoi4_agent_tools/core/result.js +0 -1
- package/dist/hoi4_agent_tools/core/scanner.js +0 -1
- package/dist/hoi4_agent_tools/core/server-state.js +0 -1
- package/dist/hoi4_agent_tools/core/source/encoding.js +0 -1
- package/dist/hoi4_agent_tools/core/source/index.js +0 -1
- package/dist/hoi4_agent_tools/core/source/lexer.js +0 -1
- package/dist/hoi4_agent_tools/core/source/limits.js +0 -1
- package/dist/hoi4_agent_tools/core/source/localisation.js +0 -1
- package/dist/hoi4_agent_tools/core/source/parser.js +0 -1
- package/dist/hoi4_agent_tools/core/source/rewrite.js +0 -1
- package/dist/hoi4_agent_tools/core/svg-text.js +0 -1
- package/dist/hoi4_agent_tools/core/transaction-limits.js +0 -1
- package/dist/hoi4_agent_tools/core/transactions.js +46 -31
- package/dist/hoi4_agent_tools/core/workspace.js +112 -396
- package/dist/hoi4_agent_tools/focus/compiler.js +0 -1
- package/dist/hoi4_agent_tools/focus/continuous-render.js +0 -1
- package/dist/hoi4_agent_tools/focus/drift.js +0 -1
- package/dist/hoi4_agent_tools/focus/geometry.js +0 -1
- package/dist/hoi4_agent_tools/focus/importer.js +0 -1
- package/dist/hoi4_agent_tools/focus/index.js +0 -1
- package/dist/hoi4_agent_tools/focus/layout.js +0 -1
- package/dist/hoi4_agent_tools/focus/limits.js +0 -1
- package/dist/hoi4_agent_tools/focus/lint.js +0 -1
- package/dist/hoi4_agent_tools/focus/model.js +0 -1
- package/dist/hoi4_agent_tools/focus/native-effects.js +0 -1
- package/dist/hoi4_agent_tools/focus/planning.js +0 -1
- package/dist/hoi4_agent_tools/focus/presentation.js +0 -1
- package/dist/hoi4_agent_tools/focus/render.js +0 -1
- package/dist/hoi4_agent_tools/focus/service.js +11 -26
- package/dist/hoi4_agent_tools/focus/source-update.js +1 -2
- package/dist/hoi4_agent_tools/gui/animation-manifest.js +0 -1
- package/dist/hoi4_agent_tools/gui/assets.js +0 -1
- package/dist/hoi4_agent_tools/gui/dds.js +0 -1
- package/dist/hoi4_agent_tools/gui/helpers.js +1 -2
- package/dist/hoi4_agent_tools/gui/index.js +0 -1
- package/dist/hoi4_agent_tools/gui/layout.js +0 -1
- package/dist/hoi4_agent_tools/gui/limits.js +0 -1
- package/dist/hoi4_agent_tools/gui/renderer.js +0 -1
- package/dist/hoi4_agent_tools/gui/scenario.js +0 -1
- package/dist/hoi4_agent_tools/gui/source-graph.js +0 -1
- package/dist/hoi4_agent_tools/gui/source-patch.js +1 -2
- package/dist/hoi4_agent_tools/gui/studio.js +247 -103
- package/dist/hoi4_agent_tools/gui/tga.js +0 -1
- package/dist/hoi4_agent_tools/gui/types.js +0 -1
- package/dist/hoi4_agent_tools/gui/validators.js +0 -1
- package/dist/hoi4_agent_tools/map/bmp.js +0 -1
- package/dist/hoi4_agent_tools/map/diagnostic-limit.js +0 -1
- package/dist/hoi4_agent_tools/map/index.js +0 -1
- package/dist/hoi4_agent_tools/map/limits.js +2 -1
- package/dist/hoi4_agent_tools/map/model.js +0 -1
- package/dist/hoi4_agent_tools/map/operations.js +0 -1
- package/dist/hoi4_agent_tools/map/render.js +0 -1
- package/dist/hoi4_agent_tools/map/service.js +182 -38
- package/dist/hoi4_agent_tools/map/validation.js +0 -1
- package/dist/hoi4_agent_tools/mcp/resources/register.js +61 -187
- package/dist/hoi4_agent_tools/mcp/security/auth.js +1 -5
- package/dist/hoi4_agent_tools/mcp/server/base-tools.js +26 -733
- package/dist/hoi4_agent_tools/mcp/server/create.js +3 -6
- package/dist/hoi4_agent_tools/mcp/server/output-schemas.js +0 -70
- package/dist/hoi4_agent_tools/mcp/server/progress.js +0 -1
- package/dist/hoi4_agent_tools/mcp/server/result.js +24 -30
- package/dist/hoi4_agent_tools/mcp/server/transaction-execution.js +123 -0
- package/dist/hoi4_agent_tools/mcp/tools/focus.js +244 -254
- package/dist/hoi4_agent_tools/mcp/tools/gui.js +163 -236
- package/dist/hoi4_agent_tools/mcp/tools/map.js +269 -323
- package/dist/hoi4_agent_tools/mcp/tools/mods.js +54 -0
- package/dist/hoi4_agent_tools/mcp/transports/bounded-stdio.js +0 -1
- package/dist/hoi4_agent_tools/mcp/transports/event-store.js +0 -1
- package/dist/hoi4_agent_tools/mcp/transports/http.js +1 -9
- package/dist/hoi4_agent_tools/mcp/transports/protocol-gate.js +0 -1
- package/dist/hoi4_agent_tools/runtime.js +5 -2
- package/dist/hoi4_agent_tools/schemas/common.js +1 -2
- package/dist/hoi4_agent_tools/schemas/focus.js +0 -1
- package/dist/hoi4_agent_tools/schemas/map.js +0 -1
- package/dist/hoi4_agent_tools/schemas/transaction.js +0 -1
- package/dist/hoi4_agent_tools/version.js +1 -2
- package/docs/README.md +8 -21
- package/docs/development.md +22 -0
- package/docs/focus.md +40 -0
- package/docs/gui.md +37 -0
- package/docs/http.md +53 -0
- package/docs/map.md +39 -0
- package/docs/setup.md +39 -0
- package/package.json +10 -11
- package/server.json +3 -12
- package/dist/bin/http.d.ts +0 -3
- package/dist/bin/http.d.ts.map +0 -1
- package/dist/bin/http.js.map +0 -1
- package/dist/bin/setup.d.ts +0 -3
- package/dist/bin/setup.d.ts.map +0 -1
- package/dist/bin/setup.js.map +0 -1
- package/dist/bin/stdio.d.ts +0 -3
- package/dist/bin/stdio.d.ts.map +0 -1
- package/dist/bin/stdio.js.map +0 -1
- package/dist/hoi4_agent_tools/core/artifacts.d.ts +0 -117
- package/dist/hoi4_agent_tools/core/artifacts.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/core/artifacts.js.map +0 -1
- package/dist/hoi4_agent_tools/core/canonical.d.ts +0 -13
- package/dist/hoi4_agent_tools/core/canonical.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/core/canonical.js.map +0 -1
- package/dist/hoi4_agent_tools/core/configuration.d.ts +0 -137
- package/dist/hoi4_agent_tools/core/configuration.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/core/configuration.js.map +0 -1
- package/dist/hoi4_agent_tools/core/diagnostic-collector.d.ts +0 -18
- package/dist/hoi4_agent_tools/core/diagnostic-collector.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/core/diagnostic-collector.js.map +0 -1
- package/dist/hoi4_agent_tools/core/diagnostics.d.ts +0 -26
- package/dist/hoi4_agent_tools/core/diagnostics.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/core/diagnostics.js.map +0 -1
- package/dist/hoi4_agent_tools/core/diff.d.ts +0 -22
- package/dist/hoi4_agent_tools/core/diff.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/core/diff.js.map +0 -1
- package/dist/hoi4_agent_tools/core/engine.d.ts +0 -56
- package/dist/hoi4_agent_tools/core/engine.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/core/engine.js.map +0 -1
- package/dist/hoi4_agent_tools/core/image-diff.d.ts +0 -14
- package/dist/hoi4_agent_tools/core/image-diff.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/core/image-diff.js.map +0 -1
- package/dist/hoi4_agent_tools/core/index.d.ts +0 -64
- package/dist/hoi4_agent_tools/core/index.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/core/index.js.map +0 -1
- package/dist/hoi4_agent_tools/core/index.public.d.ts +0 -16
- package/dist/hoi4_agent_tools/core/index.public.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/core/index.public.js +0 -16
- package/dist/hoi4_agent_tools/core/index.public.js.map +0 -1
- package/dist/hoi4_agent_tools/core/render-budget.d.ts +0 -51
- package/dist/hoi4_agent_tools/core/render-budget.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/core/render-budget.js.map +0 -1
- package/dist/hoi4_agent_tools/core/result.d.ts +0 -45
- package/dist/hoi4_agent_tools/core/result.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/core/result.js.map +0 -1
- package/dist/hoi4_agent_tools/core/scanner.d.ts +0 -28
- package/dist/hoi4_agent_tools/core/scanner.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/core/scanner.js.map +0 -1
- package/dist/hoi4_agent_tools/core/server-state.d.ts +0 -31
- package/dist/hoi4_agent_tools/core/server-state.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/core/server-state.js.map +0 -1
- package/dist/hoi4_agent_tools/core/source/encoding.d.ts +0 -10
- package/dist/hoi4_agent_tools/core/source/encoding.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/core/source/encoding.js.map +0 -1
- package/dist/hoi4_agent_tools/core/source/index.d.ts +0 -7
- package/dist/hoi4_agent_tools/core/source/index.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/core/source/index.js.map +0 -1
- package/dist/hoi4_agent_tools/core/source/lexer.d.ts +0 -30
- package/dist/hoi4_agent_tools/core/source/lexer.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/core/source/lexer.js.map +0 -1
- package/dist/hoi4_agent_tools/core/source/limits.d.ts +0 -21
- package/dist/hoi4_agent_tools/core/source/limits.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/core/source/limits.js.map +0 -1
- package/dist/hoi4_agent_tools/core/source/localisation.d.ts +0 -20
- package/dist/hoi4_agent_tools/core/source/localisation.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/core/source/localisation.js.map +0 -1
- package/dist/hoi4_agent_tools/core/source/parser.d.ts +0 -44
- package/dist/hoi4_agent_tools/core/source/parser.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/core/source/parser.js.map +0 -1
- package/dist/hoi4_agent_tools/core/source/rewrite.d.ts +0 -10
- package/dist/hoi4_agent_tools/core/source/rewrite.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/core/source/rewrite.js.map +0 -1
- package/dist/hoi4_agent_tools/core/svg-text.d.ts +0 -34
- package/dist/hoi4_agent_tools/core/svg-text.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/core/svg-text.js.map +0 -1
- package/dist/hoi4_agent_tools/core/transaction-limits.d.ts +0 -9
- package/dist/hoi4_agent_tools/core/transaction-limits.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/core/transaction-limits.js.map +0 -1
- package/dist/hoi4_agent_tools/core/transactions.d.ts +0 -162
- package/dist/hoi4_agent_tools/core/transactions.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/core/transactions.js.map +0 -1
- package/dist/hoi4_agent_tools/core/workspace.d.ts +0 -68
- package/dist/hoi4_agent_tools/core/workspace.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/core/workspace.js.map +0 -1
- package/dist/hoi4_agent_tools/focus/compiler.d.ts +0 -10
- package/dist/hoi4_agent_tools/focus/compiler.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/focus/compiler.js.map +0 -1
- package/dist/hoi4_agent_tools/focus/continuous-render.d.ts +0 -32
- package/dist/hoi4_agent_tools/focus/continuous-render.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/focus/continuous-render.js.map +0 -1
- package/dist/hoi4_agent_tools/focus/drift.d.ts +0 -22
- package/dist/hoi4_agent_tools/focus/drift.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/focus/drift.js.map +0 -1
- package/dist/hoi4_agent_tools/focus/geometry.d.ts +0 -17
- package/dist/hoi4_agent_tools/focus/geometry.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/focus/geometry.js.map +0 -1
- package/dist/hoi4_agent_tools/focus/importer.d.ts +0 -9
- package/dist/hoi4_agent_tools/focus/importer.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/focus/importer.js.map +0 -1
- package/dist/hoi4_agent_tools/focus/index.d.ts +0 -14
- package/dist/hoi4_agent_tools/focus/index.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/focus/index.js.map +0 -1
- package/dist/hoi4_agent_tools/focus/layout.d.ts +0 -5
- package/dist/hoi4_agent_tools/focus/layout.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/focus/layout.js.map +0 -1
- package/dist/hoi4_agent_tools/focus/limits.d.ts +0 -9
- package/dist/hoi4_agent_tools/focus/limits.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/focus/limits.js.map +0 -1
- package/dist/hoi4_agent_tools/focus/lint.d.ts +0 -14
- package/dist/hoi4_agent_tools/focus/lint.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/focus/lint.js.map +0 -1
- package/dist/hoi4_agent_tools/focus/model.d.ts +0 -307
- package/dist/hoi4_agent_tools/focus/model.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/focus/model.js.map +0 -1
- package/dist/hoi4_agent_tools/focus/native-effects.d.ts +0 -9
- package/dist/hoi4_agent_tools/focus/native-effects.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/focus/native-effects.js.map +0 -1
- package/dist/hoi4_agent_tools/focus/planning.d.ts +0 -15
- package/dist/hoi4_agent_tools/focus/planning.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/focus/planning.js.map +0 -1
- package/dist/hoi4_agent_tools/focus/presentation.d.ts +0 -24
- package/dist/hoi4_agent_tools/focus/presentation.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/focus/presentation.js.map +0 -1
- package/dist/hoi4_agent_tools/focus/render.d.ts +0 -39
- package/dist/hoi4_agent_tools/focus/render.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/focus/render.js.map +0 -1
- package/dist/hoi4_agent_tools/focus/service.d.ts +0 -82
- package/dist/hoi4_agent_tools/focus/service.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/focus/service.js.map +0 -1
- package/dist/hoi4_agent_tools/focus/source-update.d.ts +0 -6
- package/dist/hoi4_agent_tools/focus/source-update.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/focus/source-update.js.map +0 -1
- package/dist/hoi4_agent_tools/gui/animation-manifest.d.ts +0 -37
- package/dist/hoi4_agent_tools/gui/animation-manifest.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/gui/animation-manifest.js.map +0 -1
- package/dist/hoi4_agent_tools/gui/assets.d.ts +0 -71
- package/dist/hoi4_agent_tools/gui/assets.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/gui/assets.js.map +0 -1
- package/dist/hoi4_agent_tools/gui/dds.d.ts +0 -17
- package/dist/hoi4_agent_tools/gui/dds.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/gui/dds.js.map +0 -1
- package/dist/hoi4_agent_tools/gui/helpers.d.ts +0 -101
- package/dist/hoi4_agent_tools/gui/helpers.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/gui/helpers.js.map +0 -1
- package/dist/hoi4_agent_tools/gui/index.d.ts +0 -15
- package/dist/hoi4_agent_tools/gui/index.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/gui/index.js.map +0 -1
- package/dist/hoi4_agent_tools/gui/layout.d.ts +0 -6
- package/dist/hoi4_agent_tools/gui/layout.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/gui/layout.js.map +0 -1
- package/dist/hoi4_agent_tools/gui/limits.d.ts +0 -25
- package/dist/hoi4_agent_tools/gui/limits.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/gui/limits.js.map +0 -1
- package/dist/hoi4_agent_tools/gui/renderer.d.ts +0 -18
- package/dist/hoi4_agent_tools/gui/renderer.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/gui/renderer.js.map +0 -1
- package/dist/hoi4_agent_tools/gui/scenario.d.ts +0 -66
- package/dist/hoi4_agent_tools/gui/scenario.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/gui/scenario.js.map +0 -1
- package/dist/hoi4_agent_tools/gui/source-graph.d.ts +0 -7
- package/dist/hoi4_agent_tools/gui/source-graph.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/gui/source-graph.js.map +0 -1
- package/dist/hoi4_agent_tools/gui/source-patch.d.ts +0 -13
- package/dist/hoi4_agent_tools/gui/source-patch.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/gui/source-patch.js.map +0 -1
- package/dist/hoi4_agent_tools/gui/studio.d.ts +0 -86
- package/dist/hoi4_agent_tools/gui/studio.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/gui/studio.js.map +0 -1
- package/dist/hoi4_agent_tools/gui/tga.d.ts +0 -16
- package/dist/hoi4_agent_tools/gui/tga.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/gui/tga.js.map +0 -1
- package/dist/hoi4_agent_tools/gui/types.d.ts +0 -322
- package/dist/hoi4_agent_tools/gui/types.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/gui/types.js.map +0 -1
- package/dist/hoi4_agent_tools/gui/validators.d.ts +0 -8
- package/dist/hoi4_agent_tools/gui/validators.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/gui/validators.js.map +0 -1
- package/dist/hoi4_agent_tools/map/bmp.d.ts +0 -62
- package/dist/hoi4_agent_tools/map/bmp.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/map/bmp.js.map +0 -1
- package/dist/hoi4_agent_tools/map/diagnostic-limit.d.ts +0 -5
- package/dist/hoi4_agent_tools/map/diagnostic-limit.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/map/diagnostic-limit.js.map +0 -1
- package/dist/hoi4_agent_tools/map/index.d.ts +0 -8
- package/dist/hoi4_agent_tools/map/index.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/map/index.js.map +0 -1
- package/dist/hoi4_agent_tools/map/limits.d.ts +0 -13
- package/dist/hoi4_agent_tools/map/limits.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/map/limits.js.map +0 -1
- package/dist/hoi4_agent_tools/map/model.d.ts +0 -269
- package/dist/hoi4_agent_tools/map/model.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/map/model.js.map +0 -1
- package/dist/hoi4_agent_tools/map/operations.d.ts +0 -401
- package/dist/hoi4_agent_tools/map/operations.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/map/operations.js.map +0 -1
- package/dist/hoi4_agent_tools/map/render.d.ts +0 -90
- package/dist/hoi4_agent_tools/map/render.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/map/render.js.map +0 -1
- package/dist/hoi4_agent_tools/map/service.d.ts +0 -81
- package/dist/hoi4_agent_tools/map/service.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/map/service.js.map +0 -1
- package/dist/hoi4_agent_tools/map/validation.d.ts +0 -23
- package/dist/hoi4_agent_tools/map/validation.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/map/validation.js.map +0 -1
- package/dist/hoi4_agent_tools/mcp/prompts/register.d.ts +0 -3
- package/dist/hoi4_agent_tools/mcp/prompts/register.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/mcp/prompts/register.js +0 -50
- package/dist/hoi4_agent_tools/mcp/prompts/register.js.map +0 -1
- package/dist/hoi4_agent_tools/mcp/registry/metadata.d.ts +0 -9
- package/dist/hoi4_agent_tools/mcp/registry/metadata.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/mcp/registry/metadata.js +0 -10
- package/dist/hoi4_agent_tools/mcp/registry/metadata.js.map +0 -1
- package/dist/hoi4_agent_tools/mcp/resources/register.d.ts +0 -5
- package/dist/hoi4_agent_tools/mcp/resources/register.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/mcp/resources/register.js.map +0 -1
- package/dist/hoi4_agent_tools/mcp/security/auth.d.ts +0 -24
- package/dist/hoi4_agent_tools/mcp/security/auth.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/mcp/security/auth.js.map +0 -1
- package/dist/hoi4_agent_tools/mcp/server/base-tools.d.ts +0 -35
- package/dist/hoi4_agent_tools/mcp/server/base-tools.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/mcp/server/base-tools.js.map +0 -1
- package/dist/hoi4_agent_tools/mcp/server/create.d.ts +0 -5
- package/dist/hoi4_agent_tools/mcp/server/create.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/mcp/server/create.js.map +0 -1
- package/dist/hoi4_agent_tools/mcp/server/output-schemas.d.ts +0 -133
- package/dist/hoi4_agent_tools/mcp/server/output-schemas.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/mcp/server/output-schemas.js.map +0 -1
- package/dist/hoi4_agent_tools/mcp/server/progress.d.ts +0 -8
- package/dist/hoi4_agent_tools/mcp/server/progress.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/mcp/server/progress.js.map +0 -1
- package/dist/hoi4_agent_tools/mcp/server/result.d.ts +0 -232
- package/dist/hoi4_agent_tools/mcp/server/result.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/mcp/server/result.js.map +0 -1
- package/dist/hoi4_agent_tools/mcp/tools/focus.d.ts +0 -5
- package/dist/hoi4_agent_tools/mcp/tools/focus.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/mcp/tools/focus.js.map +0 -1
- package/dist/hoi4_agent_tools/mcp/tools/gui.d.ts +0 -111
- package/dist/hoi4_agent_tools/mcp/tools/gui.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/mcp/tools/gui.js.map +0 -1
- package/dist/hoi4_agent_tools/mcp/tools/map.d.ts +0 -5
- package/dist/hoi4_agent_tools/mcp/tools/map.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/mcp/tools/map.js.map +0 -1
- package/dist/hoi4_agent_tools/mcp/transports/bounded-stdio.d.ts +0 -58
- package/dist/hoi4_agent_tools/mcp/transports/bounded-stdio.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/mcp/transports/bounded-stdio.js.map +0 -1
- package/dist/hoi4_agent_tools/mcp/transports/event-store.d.ts +0 -26
- package/dist/hoi4_agent_tools/mcp/transports/event-store.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/mcp/transports/event-store.js.map +0 -1
- package/dist/hoi4_agent_tools/mcp/transports/http.d.ts +0 -28
- package/dist/hoi4_agent_tools/mcp/transports/http.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/mcp/transports/http.js.map +0 -1
- package/dist/hoi4_agent_tools/mcp/transports/protocol-gate.d.ts +0 -15
- package/dist/hoi4_agent_tools/mcp/transports/protocol-gate.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/mcp/transports/protocol-gate.js.map +0 -1
- package/dist/hoi4_agent_tools/runtime.d.ts +0 -4
- package/dist/hoi4_agent_tools/runtime.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/runtime.js.map +0 -1
- package/dist/hoi4_agent_tools/schemas/common.d.ts +0 -74
- package/dist/hoi4_agent_tools/schemas/common.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/schemas/common.js.map +0 -1
- package/dist/hoi4_agent_tools/schemas/focus.d.ts +0 -784
- package/dist/hoi4_agent_tools/schemas/focus.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/schemas/focus.js.map +0 -1
- package/dist/hoi4_agent_tools/schemas/index.d.ts +0 -5
- package/dist/hoi4_agent_tools/schemas/index.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/schemas/index.js +0 -5
- package/dist/hoi4_agent_tools/schemas/index.js.map +0 -1
- package/dist/hoi4_agent_tools/schemas/map.d.ts +0 -654
- package/dist/hoi4_agent_tools/schemas/map.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/schemas/map.js.map +0 -1
- package/dist/hoi4_agent_tools/schemas/transaction.d.ts +0 -259
- package/dist/hoi4_agent_tools/schemas/transaction.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/schemas/transaction.js.map +0 -1
- package/dist/hoi4_agent_tools/version.d.ts +0 -6
- package/dist/hoi4_agent_tools/version.d.ts.map +0 -1
- package/dist/hoi4_agent_tools/version.js.map +0 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -3
- package/dist/index.js.map +0 -1
- package/docs/adr/0001-runtime-and-language.md +0 -16
- package/docs/adr/0002-lossless-source-model.md +0 -18
- package/docs/adr/0003-image-and-font-codecs.md +0 -18
- package/docs/adr/0004-focus-layout.md +0 -16
- package/docs/adr/0005-offline-rendering.md +0 -18
- package/docs/adr/0006-mcp-sdk-and-protocol.md +0 -16
- package/docs/adr/0007-storage-and-transactions.md +0 -24
- package/docs/adr/0008-test-strategy.md +0 -18
- package/docs/adr/0009-packaging-and-registry.md +0 -16
- package/docs/adr/0010-unsupported-and-refusal-policy.md +0 -18
- package/docs/adr/0011-http-security.md +0 -16
- package/docs/adr/README.md +0 -13
- package/docs/agent-integration.md +0 -136
- package/docs/architecture.md +0 -60
- package/docs/artifacts.md +0 -133
- package/docs/compatibility.md +0 -33
- package/docs/completion-report.md +0 -162
- package/docs/configuration.md +0 -289
- package/docs/focus-workflow.md +0 -195
- package/docs/gui-workflow.md +0 -121
- package/docs/limitations.md +0 -31
- package/docs/map-workflow.md +0 -89
- package/docs/performance.md +0 -117
- package/docs/release.md +0 -220
- package/docs/research/mcp-2026-07-10.md +0 -46
- package/docs/research/source-ledger.md +0 -68
- package/docs/security.md +0 -139
- package/docs/self-hosting.md +0 -168
- package/docs/testing.md +0 -43
- package/docs/third-party-notices.md +0 -11
- package/docs/transactions.md +0 -168
- package/docs/troubleshooting.md +0 -46
- package/schemas/configuration.schema.json +0 -794
- package/schemas/continuous-focus-palette.schema.json +0 -325
- package/schemas/focus-plan.schema.json +0 -927
- package/schemas/focus-planning-sidecar.schema.json +0 -379
- package/schemas/gui-animation-source.schema.json +0 -176
- package/schemas/gui-helper.schema.json +0 -301
- package/schemas/gui-scenario.schema.json +0 -298
- package/schemas/map-operation.schema.json +0 -2284
- package/schemas/operation-result.schema.json +0 -344
- package/schemas/transaction-manifest.schema.json +0 -685
|
@@ -1,17 +1,135 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import fg from 'fast-glob';
|
|
3
|
-
import { ArtifactStore, boundedSourceHashEvidence, } from '../core/artifacts.js';
|
|
3
|
+
import { ArtifactStore, boundedSourceHashEvidence, publicArtifactLink, } from '../core/artifacts.js';
|
|
4
4
|
import { canonicalJson, compareCodeUnits, hashCanonical, sha256Bytes } from '../core/canonical.js';
|
|
5
5
|
import { sortDiagnostics } from '../core/diagnostics.js';
|
|
6
6
|
import { CoreEngine } from '../core/engine.js';
|
|
7
7
|
import { RenderBudget } from '../core/render-budget.js';
|
|
8
|
+
import { ServiceError } from '../core/result.js';
|
|
8
9
|
import { WorkspaceScanner } from '../core/scanner.js';
|
|
9
10
|
import { readDependenciesFromScannedFiles, } from '../core/transactions.js';
|
|
10
11
|
import { PACKAGE_VERSION } from '../version.js';
|
|
11
|
-
import {
|
|
12
|
+
import { MAP_PROVINCE_GEOMETRY_SELECTOR_LIMIT, MAP_SELECTED_OFFSET_BYTES, MAP_SELECTED_PIXEL_LIMIT, } from './limits.js';
|
|
13
|
+
import { defaultMapSelectorValue, MapWorkspaceIndex, } from './model.js';
|
|
12
14
|
import { planMapOperationsAsync } from './operations.js';
|
|
13
15
|
import { renderMap, renderMapDiff, } from './render.js';
|
|
14
16
|
import { validateMapAsync } from './validation.js';
|
|
17
|
+
function compareNumbers(left, right) {
|
|
18
|
+
return left - right;
|
|
19
|
+
}
|
|
20
|
+
function exactGeometryBounds(geometry) {
|
|
21
|
+
return {
|
|
22
|
+
minX: geometry.minX,
|
|
23
|
+
minY: geometry.minY,
|
|
24
|
+
maxXExclusive: geometry.maxX + 1,
|
|
25
|
+
maxYExclusive: geometry.maxY + 1,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function assertProvinceGeometryExportPixelBudget(pixelCount) {
|
|
29
|
+
if (!Number.isSafeInteger(pixelCount) || pixelCount < 0) {
|
|
30
|
+
throw new ServiceError('MAP_SELECTED_PIXEL_BUDGET_BLOCKED', 'Province geometry export declares an invalid selected-pixel count', {
|
|
31
|
+
source: 'Province geometry export',
|
|
32
|
+
selectedPixels: pixelCount,
|
|
33
|
+
maximumSelectedPixels: MAP_SELECTED_PIXEL_LIMIT,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
if (pixelCount > MAP_SELECTED_PIXEL_LIMIT) {
|
|
37
|
+
throw new ServiceError('MAP_SELECTED_PIXEL_BUDGET_BLOCKED', 'Province geometry export exceeds the fixed selected-pixel memory budget', {
|
|
38
|
+
source: 'Province geometry export',
|
|
39
|
+
selectedPixels: pixelCount,
|
|
40
|
+
maximumSelectedPixels: MAP_SELECTED_PIXEL_LIMIT,
|
|
41
|
+
maximumOffsetBytes: MAP_SELECTED_PIXEL_LIMIT * MAP_SELECTED_OFFSET_BYTES,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Export maximal, canonical row runs from the same raster used by map rewrites.
|
|
47
|
+
* Runs are collected in raster order, so every province's tuples are sorted by
|
|
48
|
+
* y and then startX without a second, memory-heavy sort.
|
|
49
|
+
*/
|
|
50
|
+
export async function exportProvinceGeometryRowRuns(source, provinceIds, signal) {
|
|
51
|
+
signal?.throwIfAborted();
|
|
52
|
+
if (provinceIds.length > MAP_PROVINCE_GEOMETRY_SELECTOR_LIMIT) {
|
|
53
|
+
throw new ServiceError('MAP_PROVINCE_GEOMETRY_SELECTOR_LIMIT', `Province geometry inspection accepts at most ${MAP_PROVINCE_GEOMETRY_SELECTOR_LIMIT} IDs`, {
|
|
54
|
+
requestedProvinceCount: provinceIds.length,
|
|
55
|
+
maximumProvinceCount: MAP_PROVINCE_GEOMETRY_SELECTOR_LIMIT,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
if (provinceIds.some((provinceId) => !Number.isSafeInteger(provinceId) || provinceId < 0)) {
|
|
59
|
+
throw new ServiceError('MAP_PROVINCE_GEOMETRY_SELECTOR_INVALID', 'Province geometry inspection IDs must be non-negative safe integers');
|
|
60
|
+
}
|
|
61
|
+
const raster = source.raster;
|
|
62
|
+
if (raster === undefined) {
|
|
63
|
+
throw new ServiceError('MAP_PROVINCE_BITMAP_MISSING', 'Exact province geometry inspection requires provinces.bmp');
|
|
64
|
+
}
|
|
65
|
+
const requestedProvinceIds = [...new Set(provinceIds)].sort(compareNumbers);
|
|
66
|
+
const unknownProvinceIds = requestedProvinceIds.filter((provinceId) => !source.definitionsById.has(provinceId));
|
|
67
|
+
const missingGeometryProvinceIds = requestedProvinceIds.filter((provinceId) => source.definitionsById.has(provinceId) && !raster.geometry.has(provinceId));
|
|
68
|
+
const exportableProvinceIds = requestedProvinceIds.filter((provinceId) => source.definitionsById.has(provinceId) && raster.geometry.has(provinceId));
|
|
69
|
+
let pixelCount = 0;
|
|
70
|
+
for (const provinceId of exportableProvinceIds) {
|
|
71
|
+
const geometry = raster.geometry.get(provinceId);
|
|
72
|
+
if (geometry === undefined)
|
|
73
|
+
continue;
|
|
74
|
+
pixelCount += geometry.pixelCount;
|
|
75
|
+
assertProvinceGeometryExportPixelBudget(pixelCount);
|
|
76
|
+
}
|
|
77
|
+
const rowRunsByProvince = new Map(exportableProvinceIds.map((provinceId) => [provinceId, []]));
|
|
78
|
+
const observedPixelCounts = new Map(exportableProvinceIds.map((provinceId) => [provinceId, 0]));
|
|
79
|
+
for (let y = 0; y < raster.height; y += 1) {
|
|
80
|
+
if (y % 32 === 0) {
|
|
81
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
82
|
+
signal?.throwIfAborted();
|
|
83
|
+
}
|
|
84
|
+
let x = 0;
|
|
85
|
+
while (x < raster.width) {
|
|
86
|
+
const provinceId = raster.provinceIds[y * raster.width + x] ?? -1;
|
|
87
|
+
const startX = x;
|
|
88
|
+
x += 1;
|
|
89
|
+
while (x < raster.width && (raster.provinceIds[y * raster.width + x] ?? -1) === provinceId) {
|
|
90
|
+
x += 1;
|
|
91
|
+
}
|
|
92
|
+
const runs = rowRunsByProvince.get(provinceId);
|
|
93
|
+
if (runs === undefined)
|
|
94
|
+
continue;
|
|
95
|
+
runs.push([y, startX, x]);
|
|
96
|
+
observedPixelCounts.set(provinceId, (observedPixelCounts.get(provinceId) ?? 0) + x - startX);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
signal?.throwIfAborted();
|
|
100
|
+
const provinces = exportableProvinceIds.map((provinceId) => {
|
|
101
|
+
const geometry = raster.geometry.get(provinceId);
|
|
102
|
+
if (geometry === undefined) {
|
|
103
|
+
throw new ServiceError('MAP_RASTER_GEOMETRY_MISMATCH', 'Province geometry disappeared during exact row-run export', { provinceId });
|
|
104
|
+
}
|
|
105
|
+
const observedPixelCount = observedPixelCounts.get(provinceId) ?? 0;
|
|
106
|
+
if (observedPixelCount !== geometry.pixelCount) {
|
|
107
|
+
throw new ServiceError('MAP_RASTER_GEOMETRY_MISMATCH', 'Exact province row runs do not match the indexed province pixel count', {
|
|
108
|
+
provinceId,
|
|
109
|
+
expectedPixelCount: geometry.pixelCount,
|
|
110
|
+
observedPixelCount,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
const rowRuns = rowRunsByProvince.get(provinceId) ?? [];
|
|
114
|
+
return {
|
|
115
|
+
provinceId,
|
|
116
|
+
pixelCount: observedPixelCount,
|
|
117
|
+
bounds: exactGeometryBounds(geometry),
|
|
118
|
+
rowRunCount: rowRuns.length,
|
|
119
|
+
rowRuns,
|
|
120
|
+
};
|
|
121
|
+
});
|
|
122
|
+
return {
|
|
123
|
+
width: raster.width,
|
|
124
|
+
height: raster.height,
|
|
125
|
+
requestedProvinceIds,
|
|
126
|
+
unknownProvinceIds,
|
|
127
|
+
missingGeometryProvinceIds,
|
|
128
|
+
pixelCount,
|
|
129
|
+
rowRunCount: provinces.reduce((count, province) => count + province.rowRunCount, 0),
|
|
130
|
+
provinces,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
15
133
|
const provinceOperationKinds = new Set([
|
|
16
134
|
'split_province',
|
|
17
135
|
'create_province',
|
|
@@ -181,7 +299,7 @@ export function attributeMapValidationDiagnostics(input) {
|
|
|
181
299
|
attributed.push({
|
|
182
300
|
code: 'MAP_VALIDATION_OPERATION_UNOWNED',
|
|
183
301
|
severity: 'blocker',
|
|
184
|
-
category: '
|
|
302
|
+
category: 'validation',
|
|
185
303
|
message: `${diagnostic.code} already existed before the manifest and has no originating operation`,
|
|
186
304
|
...(diagnostic.location === undefined ? {} : { location: diagnostic.location }),
|
|
187
305
|
...(diagnostic.related === undefined ? {} : { related: diagnostic.related }),
|
|
@@ -238,7 +356,7 @@ export function attributeMapValidationDiagnostics(input) {
|
|
|
238
356
|
attributed.push({
|
|
239
357
|
code: 'MAP_VALIDATION_OPERATION_UNOWNED',
|
|
240
358
|
severity: 'blocker',
|
|
241
|
-
category: '
|
|
359
|
+
category: 'validation',
|
|
242
360
|
message: `${diagnostic.code} cannot be attributed to any manifest operation`,
|
|
243
361
|
...(diagnostic.location === undefined ? {} : { location: diagnostic.location }),
|
|
244
362
|
...(diagnostic.related === undefined ? {} : { related: diagnostic.related }),
|
|
@@ -390,14 +508,14 @@ export class AgentNudger {
|
|
|
390
508
|
validation: await validateMapAsync(snapshot.index, signal === undefined ? {} : { signal }),
|
|
391
509
|
};
|
|
392
510
|
}
|
|
393
|
-
async
|
|
394
|
-
|
|
395
|
-
const snapshot = await this.scan(
|
|
396
|
-
const plan = await planMapOperationsAsync(snapshot.index,
|
|
397
|
-
const baselineValidation = await validateMapAsync(snapshot.index,
|
|
511
|
+
async prepareOperations(workspaceId, operations, principal, signal) {
|
|
512
|
+
signal?.throwIfAborted();
|
|
513
|
+
const snapshot = await this.scan(workspaceId, principal, signal);
|
|
514
|
+
const plan = await planMapOperationsAsync(snapshot.index, operations, signal);
|
|
515
|
+
const baselineValidation = await validateMapAsync(snapshot.index, signal === undefined ? {} : { signal });
|
|
398
516
|
const rawValidation = await validateMapAsync(plan.finalIndex, {
|
|
399
517
|
baseline: snapshot.index,
|
|
400
|
-
...(
|
|
518
|
+
...(signal === undefined ? {} : { signal }),
|
|
401
519
|
...(plan.expectedChangedBounds === undefined
|
|
402
520
|
? {}
|
|
403
521
|
: { expectedChangedBounds: plan.expectedChangedBounds }),
|
|
@@ -411,7 +529,22 @@ export class AgentNudger {
|
|
|
411
529
|
baselineDiagnostics: baselineValidation.diagnostics,
|
|
412
530
|
}),
|
|
413
531
|
};
|
|
414
|
-
|
|
532
|
+
return {
|
|
533
|
+
snapshot,
|
|
534
|
+
plan,
|
|
535
|
+
validation: validationWithPlan(attributedValidation, plan),
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
async plan(input) {
|
|
539
|
+
const prepared = await this.prepareOperations(input.workspaceId, input.operations, input.principal, input.signal);
|
|
540
|
+
return this.planPrepared(input, prepared);
|
|
541
|
+
}
|
|
542
|
+
async planPrepared(input, prepared) {
|
|
543
|
+
input.signal?.throwIfAborted();
|
|
544
|
+
const { snapshot, plan, validation } = prepared;
|
|
545
|
+
if (snapshot.workspaceId !== input.workspaceId) {
|
|
546
|
+
throw new ServiceError('MAP_PREPARED_WORKSPACE_MISMATCH', 'Prepared map operations belong to another workspace');
|
|
547
|
+
}
|
|
415
548
|
const transaction = await this.transactions.plan({
|
|
416
549
|
workspaceId: input.workspaceId,
|
|
417
550
|
...(input.principal === undefined ? {} : { principal: input.principal }),
|
|
@@ -424,15 +557,21 @@ export class AgentNudger {
|
|
|
424
557
|
validate: (proposed, signal) => {
|
|
425
558
|
signal?.throwIfAborted();
|
|
426
559
|
const expected = new Map(plan.changes.map((change) => [change.relativePath, change.content]));
|
|
427
|
-
const
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
560
|
+
const current = new Map(snapshot.files
|
|
561
|
+
.filter(({ rootKind, shadowedBy }) => rootKind === 'mod' && shadowedBy === undefined)
|
|
562
|
+
.map(({ relativePath, bytes }) => [relativePath, bytes]));
|
|
563
|
+
const exactProposedBytes = proposed.size <= expected.size &&
|
|
564
|
+
[...expected].every(([relativePath, planned]) => {
|
|
565
|
+
const content = proposed.has(relativePath)
|
|
566
|
+
? proposed.get(relativePath)
|
|
567
|
+
: (current.get(relativePath) ?? null);
|
|
568
|
+
if (content === undefined)
|
|
431
569
|
return false;
|
|
432
570
|
if (content === null || planned === null)
|
|
433
571
|
return content === planned;
|
|
434
572
|
return Buffer.from(content).equals(Buffer.from(planned));
|
|
435
|
-
})
|
|
573
|
+
}) &&
|
|
574
|
+
[...proposed.keys()].every((relativePath) => expected.has(relativePath));
|
|
436
575
|
const diagnostics = exactProposedBytes
|
|
437
576
|
? validation.diagnostics
|
|
438
577
|
: [
|
|
@@ -440,7 +579,7 @@ export class AgentNudger {
|
|
|
440
579
|
{
|
|
441
580
|
code: 'MAP_TRANSACTION_BYTES_MISMATCH',
|
|
442
581
|
severity: 'blocker',
|
|
443
|
-
category: '
|
|
582
|
+
category: 'validation',
|
|
444
583
|
message: 'Transaction dry-run bytes differ from the validated map operation plan',
|
|
445
584
|
},
|
|
446
585
|
];
|
|
@@ -515,26 +654,32 @@ export class AgentNudger {
|
|
|
515
654
|
};
|
|
516
655
|
}
|
|
517
656
|
async renderDiffAndStore(workspaceId, operations, options = {}) {
|
|
518
|
-
const
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
657
|
+
const prepared = await this.prepareOperations(workspaceId, operations, options.principal, options.signal);
|
|
658
|
+
return this.renderPreparedDiffAndStore(prepared, operations, options);
|
|
659
|
+
}
|
|
660
|
+
/**
|
|
661
|
+
* Build review evidence and a hash-bound transaction from one immutable scan and operation plan.
|
|
662
|
+
* Any source edit after this preparation is rejected by the transaction read-dependency checks.
|
|
663
|
+
*/
|
|
664
|
+
async planRewriteWithDiff(input) {
|
|
665
|
+
const prepared = await this.prepareOperations(input.workspaceId, input.operations, input.principal, input.signal);
|
|
666
|
+
const diff = await this.renderPreparedDiffAndStore(prepared, input.operations, {
|
|
667
|
+
...(input.diffScale === undefined ? {} : { scale: input.diffScale }),
|
|
668
|
+
...(input.principal === undefined ? {} : { principal: input.principal }),
|
|
669
|
+
...(input.signal === undefined ? {} : { signal: input.signal }),
|
|
528
670
|
});
|
|
529
|
-
const
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
671
|
+
const planned = await this.planPrepared({
|
|
672
|
+
workspaceId: input.workspaceId,
|
|
673
|
+
operations: input.operations,
|
|
674
|
+
artifacts: diff.artifacts.map(publicArtifactLink),
|
|
675
|
+
...(input.principal === undefined ? {} : { principal: input.principal }),
|
|
676
|
+
...(input.signal === undefined ? {} : { signal: input.signal }),
|
|
677
|
+
}, prepared);
|
|
678
|
+
return { ...diff, ...planned };
|
|
679
|
+
}
|
|
680
|
+
async renderPreparedDiffAndStore(prepared, operations, options) {
|
|
681
|
+
const budget = new RenderBudget();
|
|
682
|
+
const { snapshot, plan, validation } = prepared;
|
|
538
683
|
const review = {
|
|
539
684
|
operationIds: plan.operations.map(({ id }) => id),
|
|
540
685
|
affectedFiles: plan.changes.map(({ relativePath, operationIds, mediaType, content }) => ({
|
|
@@ -593,7 +738,7 @@ export class AgentNudger {
|
|
|
593
738
|
const bundle = mapBundleWithSourceHashes(rawBundle, completeSourceHashes);
|
|
594
739
|
const beforeBundle = mapBundleWithSourceHashes(rawBeforeBundle, completeSourceHashes);
|
|
595
740
|
const proposedBundle = mapBundleWithSourceHashes(rawProposedBundle, completeSourceHashes);
|
|
596
|
-
const workspace = this.resolver.get(workspaceId, options.principal);
|
|
741
|
+
const workspace = this.resolver.get(snapshot.workspaceId, options.principal);
|
|
597
742
|
const provenance = {
|
|
598
743
|
kind: 'map-diff-render',
|
|
599
744
|
toolVersion: PACKAGE_VERSION,
|
|
@@ -692,4 +837,3 @@ export class AgentNudger {
|
|
|
692
837
|
};
|
|
693
838
|
}
|
|
694
839
|
}
|
|
695
|
-
//# sourceMappingURL=service.js.map
|
|
@@ -1,11 +1,30 @@
|
|
|
1
1
|
import { ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
-
import { readFile } from 'node:fs/promises';
|
|
3
|
-
import path from 'node:path';
|
|
4
2
|
import { canonicalJson } from '../../core/canonical.js';
|
|
5
3
|
import { ServiceError } from '../../core/result.js';
|
|
6
|
-
import { compactWorkspaceStatus } from '../server/base-tools.js';
|
|
7
4
|
const artifactResourceLimit = 1_048_576;
|
|
5
|
+
const artifactChunkMetadataKey = 'io.github.klimpaskov/hoi4-agent-tools.artifact-byte-range';
|
|
8
6
|
const fatalUtf8Decoder = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true });
|
|
7
|
+
const artifactResourceMetadata = {
|
|
8
|
+
title: 'HOI4 review artifact',
|
|
9
|
+
description: 'Complete plans, diagnostics, layouts, previews, and diffs. Reads accept zero-based byte offset and positive byte length query selectors; each response reports its exact byte range and continuation URI in _meta.',
|
|
10
|
+
_meta: {
|
|
11
|
+
[artifactChunkMetadataKey]: {
|
|
12
|
+
version: 1,
|
|
13
|
+
unit: 'byte',
|
|
14
|
+
maxChunkSize: artifactResourceLimit,
|
|
15
|
+
selectors: {
|
|
16
|
+
offset: { type: 'integer', minimum: 0, default: 0 },
|
|
17
|
+
length: {
|
|
18
|
+
type: 'integer',
|
|
19
|
+
minimum: 1,
|
|
20
|
+
maximum: artifactResourceLimit,
|
|
21
|
+
default: artifactResourceLimit,
|
|
22
|
+
},
|
|
23
|
+
metadata: { type: 'string', enum: ['manifest'], optional: true },
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
};
|
|
9
28
|
function assertResourceSelectors(uri, allowed) {
|
|
10
29
|
if (uri.hash !== '' || uri.username !== '' || uri.password !== '' || uri.port !== '') {
|
|
11
30
|
throw new ServiceError('RESOURCE_URI_INVALID', 'Resource URI is not canonical');
|
|
@@ -28,31 +47,6 @@ function contentArtifactUri(uri) {
|
|
|
28
47
|
contentUri.hash = '';
|
|
29
48
|
return contentUri.href;
|
|
30
49
|
}
|
|
31
|
-
function transactionResourceIdentity(uri) {
|
|
32
|
-
let segments;
|
|
33
|
-
try {
|
|
34
|
-
segments = uri.pathname.split('/').filter(Boolean).map(decodeURIComponent);
|
|
35
|
-
}
|
|
36
|
-
catch {
|
|
37
|
-
throw new ServiceError('TRANSACTION_ID_INVALID', 'Invalid transaction resource URI');
|
|
38
|
-
}
|
|
39
|
-
if (uri.protocol !== 'hoi4-agent:' ||
|
|
40
|
-
uri.hostname !== 'workspace' ||
|
|
41
|
-
segments.length !== 3 ||
|
|
42
|
-
segments[1] !== 'transaction' ||
|
|
43
|
-
!/^[a-z][a-z0-9_-]{0,63}$/u.test(segments[0]) ||
|
|
44
|
-
!/^txn_[0-9a-f-]{36}$/u.test(segments[2])) {
|
|
45
|
-
throw new ServiceError('TRANSACTION_ID_INVALID', 'Invalid transaction resource URI');
|
|
46
|
-
}
|
|
47
|
-
const canonical = `hoi4-agent://workspace/${encodeURIComponent(segments[0])}/transaction/${encodeURIComponent(segments[2])}`;
|
|
48
|
-
const queryless = new URL(uri);
|
|
49
|
-
queryless.search = '';
|
|
50
|
-
queryless.hash = '';
|
|
51
|
-
if (queryless.href !== canonical) {
|
|
52
|
-
throw new ServiceError('TRANSACTION_ID_INVALID', 'Transaction resource URI is not canonical');
|
|
53
|
-
}
|
|
54
|
-
return { workspaceId: segments[0], transactionId: segments[2] };
|
|
55
|
-
}
|
|
56
50
|
function exactUtf8Text(bytes) {
|
|
57
51
|
try {
|
|
58
52
|
const text = fatalUtf8Decoder.decode(bytes);
|
|
@@ -62,7 +56,7 @@ function exactUtf8Text(bytes) {
|
|
|
62
56
|
return undefined;
|
|
63
57
|
}
|
|
64
58
|
}
|
|
65
|
-
function artifactRangeParameter(uri, name, fallback, minimum) {
|
|
59
|
+
function artifactRangeParameter(uri, name, fallback, minimum, maximum = Number.MAX_SAFE_INTEGER) {
|
|
66
60
|
const raw = uri.searchParams.get(name);
|
|
67
61
|
if (raw === null)
|
|
68
62
|
return fallback;
|
|
@@ -70,44 +64,40 @@ function artifactRangeParameter(uri, name, fallback, minimum) {
|
|
|
70
64
|
throw new ServiceError('ARTIFACT_RANGE_INVALID', 'Artifact byte range is invalid');
|
|
71
65
|
}
|
|
72
66
|
const value = Number(raw);
|
|
73
|
-
if (!Number.isSafeInteger(value) || value < minimum) {
|
|
67
|
+
if (!Number.isSafeInteger(value) || value < minimum || value > maximum) {
|
|
74
68
|
throw new ServiceError('ARTIFACT_RANGE_INVALID', 'Artifact byte range is invalid');
|
|
75
69
|
}
|
|
76
70
|
return value;
|
|
77
71
|
}
|
|
72
|
+
function artifactChunkMetadata(uri, metadata, totalSize, offset, returnedLength, requestedLength) {
|
|
73
|
+
const endExclusive = offset + returnedLength;
|
|
74
|
+
let continuationUri = null;
|
|
75
|
+
if (endExclusive < totalSize) {
|
|
76
|
+
const continuation = new URL(contentArtifactUri(uri));
|
|
77
|
+
continuation.searchParams.set('offset', String(endExclusive));
|
|
78
|
+
continuation.searchParams.set('length', String(requestedLength));
|
|
79
|
+
if (metadata !== null)
|
|
80
|
+
continuation.searchParams.set('metadata', metadata);
|
|
81
|
+
continuationUri = continuation.href;
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
[artifactChunkMetadataKey]: {
|
|
85
|
+
version: 1,
|
|
86
|
+
unit: 'byte',
|
|
87
|
+
totalSize,
|
|
88
|
+
returnedRange: { offset, length: returnedLength, endExclusive },
|
|
89
|
+
complete: offset === 0 && returnedLength === totalSize,
|
|
90
|
+
continuationUri,
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
}
|
|
78
94
|
export function registerMcpResources(server, engine, context) {
|
|
79
|
-
server.registerResource('
|
|
80
|
-
list: () => ({
|
|
81
|
-
resources: engine.list(context.principal).map((workspace) => ({
|
|
82
|
-
uri: `hoi4-agent://workspace/${workspace.id}/summary`,
|
|
83
|
-
name: `${workspace.name} summary`,
|
|
84
|
-
mimeType: 'application/json',
|
|
85
|
-
})),
|
|
86
|
-
}),
|
|
87
|
-
}), {
|
|
88
|
-
title: 'Workspace summary',
|
|
89
|
-
description: 'Registered workspace capabilities',
|
|
90
|
-
mimeType: 'application/json',
|
|
91
|
-
}, (uri, { workspaceId }) => {
|
|
92
|
-
assertResourceSelectors(uri, []);
|
|
93
|
-
return {
|
|
94
|
-
contents: [
|
|
95
|
-
{
|
|
96
|
-
uri: uri.href,
|
|
97
|
-
mimeType: 'application/json',
|
|
98
|
-
text: `${canonicalJson(compactWorkspaceStatus(engine.status(String(workspaceId), context.principal)))}\n`,
|
|
99
|
-
},
|
|
100
|
-
],
|
|
101
|
-
};
|
|
102
|
-
});
|
|
103
|
-
server.registerResource('artifact', new ResourceTemplate('hoi4-agent://workspace/{workspaceId}/artifact/{sha256}/{provenanceHash}/{name}', {
|
|
104
|
-
list: undefined,
|
|
105
|
-
}), { title: 'Generated artifact', description: 'Content-addressed workspace artifact' }, async (uri, { workspaceId }, extra) => {
|
|
95
|
+
server.registerResource('artifact', new ResourceTemplate('hoi4-agent://workspace/{workspaceId}/artifact/{sha256}/{provenanceHash}/{name}', { list: undefined }), artifactResourceMetadata, async (uri, { workspaceId }, extra) => {
|
|
106
96
|
extra.signal.throwIfAborted();
|
|
107
97
|
assertResourceSelectors(uri, ['offset', 'length', 'metadata']);
|
|
108
98
|
const workspace = engine.resolver.get(String(workspaceId), context.principal);
|
|
109
99
|
const offset = artifactRangeParameter(uri, 'offset', 0, 0);
|
|
110
|
-
const length =
|
|
100
|
+
const length = artifactRangeParameter(uri, 'length', artifactResourceLimit, 1, artifactResourceLimit);
|
|
111
101
|
const metadata = uri.searchParams.get('metadata');
|
|
112
102
|
if (metadata !== null && metadata !== 'manifest') {
|
|
113
103
|
throw new ServiceError('ARTIFACT_METADATA_INVALID', 'Artifact metadata selector is invalid');
|
|
@@ -119,161 +109,45 @@ export function registerMcpResources(server, engine, context) {
|
|
|
119
109
|
const manifestBytes = Buffer.from(`${canonicalJson(publicManifest)}\n`, 'utf8');
|
|
120
110
|
const start = Math.min(offset, manifestBytes.length);
|
|
121
111
|
const selected = manifestBytes.subarray(start, Math.min(manifestBytes.length, start + length));
|
|
122
|
-
extra.signal.throwIfAborted();
|
|
123
112
|
const complete = start === 0 && selected.length === manifestBytes.length;
|
|
113
|
+
const _meta = artifactChunkMetadata(uri, metadata, manifestBytes.length, start, selected.length, length);
|
|
124
114
|
return {
|
|
125
115
|
contents: [
|
|
126
116
|
complete
|
|
127
|
-
? {
|
|
117
|
+
? {
|
|
118
|
+
uri: uri.href,
|
|
119
|
+
mimeType: 'application/json',
|
|
120
|
+
text: selected.toString('utf8'),
|
|
121
|
+
_meta,
|
|
122
|
+
}
|
|
128
123
|
: {
|
|
129
124
|
uri: uri.href,
|
|
130
125
|
mimeType: 'application/json',
|
|
131
126
|
blob: selected.toString('base64'),
|
|
127
|
+
_meta,
|
|
132
128
|
},
|
|
133
129
|
],
|
|
134
130
|
};
|
|
135
131
|
}
|
|
136
132
|
const artifact = await engine.artifacts.read(workspace, contentArtifactUri(uri), { offset, length }, extra.signal);
|
|
137
|
-
extra.signal.throwIfAborted();
|
|
138
133
|
const textual = artifact.mimeType.startsWith('text/') ||
|
|
139
134
|
artifact.mimeType === 'application/json' ||
|
|
140
135
|
artifact.mimeType === 'image/svg+xml';
|
|
141
|
-
const
|
|
136
|
+
const start = Math.min(offset, artifact.totalSize);
|
|
137
|
+
const complete = start === 0 && artifact.bytes.length === artifact.totalSize;
|
|
142
138
|
const text = textual && complete ? exactUtf8Text(artifact.bytes) : undefined;
|
|
139
|
+
const _meta = artifactChunkMetadata(uri, metadata, artifact.totalSize, start, artifact.bytes.length, length);
|
|
143
140
|
return {
|
|
144
141
|
contents: [
|
|
145
142
|
text !== undefined
|
|
146
|
-
? { uri: uri.href, mimeType: artifact.mimeType, text }
|
|
143
|
+
? { uri: uri.href, mimeType: artifact.mimeType, text, _meta }
|
|
147
144
|
: {
|
|
148
145
|
uri: uri.href,
|
|
149
146
|
mimeType: artifact.mimeType,
|
|
150
147
|
blob: artifact.bytes.toString('base64'),
|
|
148
|
+
_meta,
|
|
151
149
|
},
|
|
152
150
|
],
|
|
153
151
|
};
|
|
154
152
|
});
|
|
155
|
-
server.registerResource('transaction-manifest', new ResourceTemplate('hoi4-agent://workspace/{workspaceId}/transaction/{transactionId}', {
|
|
156
|
-
list: undefined,
|
|
157
|
-
}), {
|
|
158
|
-
title: 'Transaction manifest',
|
|
159
|
-
description: 'Declarative transaction and rollback status',
|
|
160
|
-
mimeType: 'application/json',
|
|
161
|
-
}, async (uri, { workspaceId }, extra) => {
|
|
162
|
-
extra.signal.throwIfAborted();
|
|
163
|
-
assertResourceSelectors(uri, ['offset', 'length']);
|
|
164
|
-
const identity = transactionResourceIdentity(uri);
|
|
165
|
-
if (identity.workspaceId !== String(workspaceId)) {
|
|
166
|
-
throw new ServiceError('TRANSACTION_WORKSPACE_MISMATCH', 'Transaction resource does not belong to this workspace');
|
|
167
|
-
}
|
|
168
|
-
const offset = artifactRangeParameter(uri, 'offset', 0, 0);
|
|
169
|
-
const length = Math.min(artifactResourceLimit, artifactRangeParameter(uri, 'length', artifactResourceLimit, 1));
|
|
170
|
-
const manifestRange = await engine.transactions.readManifestRange(identity.workspaceId, identity.transactionId, { offset, length }, context.principal, extra.signal);
|
|
171
|
-
extra.signal.throwIfAborted();
|
|
172
|
-
const complete = offset === 0 && manifestRange.bytes.length === manifestRange.totalSize;
|
|
173
|
-
return {
|
|
174
|
-
contents: [
|
|
175
|
-
complete
|
|
176
|
-
? {
|
|
177
|
-
uri: uri.href,
|
|
178
|
-
mimeType: 'application/json',
|
|
179
|
-
text: manifestRange.bytes.toString('utf8'),
|
|
180
|
-
}
|
|
181
|
-
: {
|
|
182
|
-
uri: uri.href,
|
|
183
|
-
mimeType: 'application/json',
|
|
184
|
-
blob: manifestRange.bytes.toString('base64'),
|
|
185
|
-
},
|
|
186
|
-
],
|
|
187
|
-
};
|
|
188
|
-
});
|
|
189
|
-
const packageRoot = path.resolve(import.meta.dirname, '../../../..');
|
|
190
|
-
const documentation = new Map([
|
|
191
|
-
['agent-integration', 'docs/agent-integration.md'],
|
|
192
|
-
['architecture', 'docs/architecture.md'],
|
|
193
|
-
['artifacts', 'docs/artifacts.md'],
|
|
194
|
-
['compatibility', 'docs/compatibility.md'],
|
|
195
|
-
['configuration', 'docs/configuration.md'],
|
|
196
|
-
['focus-workflow', 'docs/focus-workflow.md'],
|
|
197
|
-
['gui-workflow', 'docs/gui-workflow.md'],
|
|
198
|
-
['limitations', 'docs/limitations.md'],
|
|
199
|
-
['map-workflow', 'docs/map-workflow.md'],
|
|
200
|
-
['security', 'docs/security.md'],
|
|
201
|
-
['self-hosting', 'docs/self-hosting.md'],
|
|
202
|
-
['testing', 'docs/testing.md'],
|
|
203
|
-
['transactions', 'docs/transactions.md'],
|
|
204
|
-
['troubleshooting', 'docs/troubleshooting.md'],
|
|
205
|
-
]);
|
|
206
|
-
server.registerResource('documentation', new ResourceTemplate('hoi4-agent://docs/{name}', {
|
|
207
|
-
list: () => ({
|
|
208
|
-
resources: [...documentation.keys()].map((name) => ({
|
|
209
|
-
uri: `hoi4-agent://docs/${name}`,
|
|
210
|
-
name: `${name} documentation`,
|
|
211
|
-
mimeType: 'text/markdown',
|
|
212
|
-
})),
|
|
213
|
-
}),
|
|
214
|
-
}), {
|
|
215
|
-
title: 'HOI4 Agent Tools documentation',
|
|
216
|
-
description: 'Versioned package documentation for coding agents',
|
|
217
|
-
mimeType: 'text/markdown',
|
|
218
|
-
}, async (uri, { name }, extra) => {
|
|
219
|
-
extra.signal.throwIfAborted();
|
|
220
|
-
assertResourceSelectors(uri, []);
|
|
221
|
-
const relative = documentation.get(String(name));
|
|
222
|
-
if (relative === undefined)
|
|
223
|
-
throw new ServiceError('RESOURCE_NOT_FOUND', 'Unknown document');
|
|
224
|
-
const contents = await readFile(path.join(packageRoot, relative), 'utf8');
|
|
225
|
-
extra.signal.throwIfAborted();
|
|
226
|
-
return {
|
|
227
|
-
contents: [
|
|
228
|
-
{
|
|
229
|
-
uri: uri.href,
|
|
230
|
-
mimeType: 'text/markdown',
|
|
231
|
-
text: contents,
|
|
232
|
-
},
|
|
233
|
-
],
|
|
234
|
-
};
|
|
235
|
-
});
|
|
236
|
-
const schemas = new Map([
|
|
237
|
-
['configuration', 'schemas/configuration.schema.json'],
|
|
238
|
-
['continuous-focus-palette', 'schemas/continuous-focus-palette.schema.json'],
|
|
239
|
-
['focus-plan', 'schemas/focus-plan.schema.json'],
|
|
240
|
-
['focus-planning-sidecar', 'schemas/focus-planning-sidecar.schema.json'],
|
|
241
|
-
['gui-animation-source', 'schemas/gui-animation-source.schema.json'],
|
|
242
|
-
['gui-helper', 'schemas/gui-helper.schema.json'],
|
|
243
|
-
['gui-scenario', 'schemas/gui-scenario.schema.json'],
|
|
244
|
-
['map-operation', 'schemas/map-operation.schema.json'],
|
|
245
|
-
['operation-result', 'schemas/operation-result.schema.json'],
|
|
246
|
-
['transaction-manifest', 'schemas/transaction-manifest.schema.json'],
|
|
247
|
-
]);
|
|
248
|
-
server.registerResource('schema', new ResourceTemplate('hoi4-agent://schema/{name}', {
|
|
249
|
-
list: () => ({
|
|
250
|
-
resources: [...schemas.keys()].map((name) => ({
|
|
251
|
-
uri: `hoi4-agent://schema/${name}`,
|
|
252
|
-
name: `${name} JSON Schema`,
|
|
253
|
-
mimeType: 'application/schema+json',
|
|
254
|
-
})),
|
|
255
|
-
}),
|
|
256
|
-
}), {
|
|
257
|
-
title: 'Public JSON Schema',
|
|
258
|
-
description: 'Versioned strict schemas shipped with the package',
|
|
259
|
-
mimeType: 'application/schema+json',
|
|
260
|
-
}, async (uri, { name }, extra) => {
|
|
261
|
-
extra.signal.throwIfAborted();
|
|
262
|
-
assertResourceSelectors(uri, []);
|
|
263
|
-
const relative = schemas.get(String(name));
|
|
264
|
-
if (relative === undefined)
|
|
265
|
-
throw new ServiceError('RESOURCE_NOT_FOUND', 'Unknown schema');
|
|
266
|
-
const contents = await readFile(path.join(packageRoot, relative), 'utf8');
|
|
267
|
-
extra.signal.throwIfAborted();
|
|
268
|
-
return {
|
|
269
|
-
contents: [
|
|
270
|
-
{
|
|
271
|
-
uri: uri.href,
|
|
272
|
-
mimeType: 'application/schema+json',
|
|
273
|
-
text: contents,
|
|
274
|
-
},
|
|
275
|
-
],
|
|
276
|
-
};
|
|
277
|
-
});
|
|
278
153
|
}
|
|
279
|
-
//# sourceMappingURL=register.js.map
|
|
@@ -136,10 +136,7 @@ export async function authenticate(authorization, configuration, requiredScopes
|
|
|
136
136
|
principal: configured.principal,
|
|
137
137
|
clientId: configured.principal,
|
|
138
138
|
credentialId: presentedCredentialId,
|
|
139
|
-
scopes: [
|
|
140
|
-
'hoi4:read',
|
|
141
|
-
...(configuration.writePolicy === 'transactions' ? ['hoi4:write'] : []),
|
|
142
|
-
],
|
|
139
|
+
scopes: ['hoi4:read', 'hoi4:write'],
|
|
143
140
|
};
|
|
144
141
|
requireScopes(principal.scopes, normalizedRequiredScopes);
|
|
145
142
|
return principal;
|
|
@@ -231,4 +228,3 @@ export function protectedResourceMetadata(configuration) {
|
|
|
231
228
|
resource_name: 'HOI4 Agent Tools',
|
|
232
229
|
};
|
|
233
230
|
}
|
|
234
|
-
//# sourceMappingURL=auth.js.map
|