cwtools-mcp 0.1.0 → 0.2.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/dist/cwtools-mcp.cjs +262 -101
- package/dist/mcp/resources.js +2 -10
- package/package.json +2 -2
package/dist/cwtools-mcp.cjs
CHANGED
|
@@ -592,6 +592,7 @@ var require_mcpTools = __commonJS({
|
|
|
592
592
|
"localisation",
|
|
593
593
|
"identifiers",
|
|
594
594
|
"validation",
|
|
595
|
+
"compatibility",
|
|
595
596
|
"promptCards",
|
|
596
597
|
"all"
|
|
597
598
|
],
|
|
@@ -751,7 +752,11 @@ var require_mcpTools = __commonJS({
|
|
|
751
752
|
},
|
|
752
753
|
"includeReferences": {
|
|
753
754
|
"type": "boolean",
|
|
754
|
-
"description": "
|
|
755
|
+
"description": "Include lightweight cross-file reference contexts. Default false."
|
|
756
|
+
},
|
|
757
|
+
"includeAssetChain": {
|
|
758
|
+
"type": "boolean",
|
|
759
|
+
"description": "Check bounded GUI/GFX/model targets, path case, and DDS frame layout."
|
|
755
760
|
},
|
|
756
761
|
"limit": {
|
|
757
762
|
"type": "number",
|
|
@@ -773,7 +778,7 @@ var require_mcpTools = __commonJS({
|
|
|
773
778
|
{
|
|
774
779
|
"tool": {
|
|
775
780
|
"name": "explore_pdx_project",
|
|
776
|
-
"description": "Primary semantic exploration
|
|
781
|
+
"description": "Primary semantic exploration for large Paradox projects: live CWTools type/reference graph with bounded nodes, edges, file facts, provenance and freshness. Use FIRST for connectivity and impact; follow with exact query_rules/query_scope/query_types/get_pdx_block before writing.",
|
|
777
782
|
"inputSchema": {
|
|
778
783
|
"type": "object",
|
|
779
784
|
"properties": {
|
|
@@ -814,6 +819,17 @@ var require_mcpTools = __commonJS({
|
|
|
814
819
|
"includeMetadata": {
|
|
815
820
|
"type": "boolean",
|
|
816
821
|
"description": "Include documentation, variables, event targets, and block metadata. Default true."
|
|
822
|
+
},
|
|
823
|
+
"relationshipKinds": {
|
|
824
|
+
"type": "array",
|
|
825
|
+
"items": {
|
|
826
|
+
"type": "string",
|
|
827
|
+
"enum": [
|
|
828
|
+
"inline_invocation",
|
|
829
|
+
"inline_expansion"
|
|
830
|
+
]
|
|
831
|
+
},
|
|
832
|
+
"description": "Extra graph kinds: inline_invocation or inline_expansion."
|
|
817
833
|
}
|
|
818
834
|
},
|
|
819
835
|
"required": []
|
|
@@ -828,6 +844,109 @@ var require_mcpTools = __commonJS({
|
|
|
828
844
|
"concurrencyClass": "lsp-limited"
|
|
829
845
|
}
|
|
830
846
|
},
|
|
847
|
+
{
|
|
848
|
+
"tool": {
|
|
849
|
+
"name": "query_inline_instantiation",
|
|
850
|
+
"description": "Preview one inline_script template instantiation: parameters, arguments, expanded symbol, and problems (missing/unused/unresolved). Precise template path or file+line only; no whole-project expansion. Use before editing a template or caller.",
|
|
851
|
+
"inputSchema": {
|
|
852
|
+
"type": "object",
|
|
853
|
+
"properties": {
|
|
854
|
+
"template": {
|
|
855
|
+
"type": "string",
|
|
856
|
+
"description": "Template path, e.g. common/inline_scripts/example.txt."
|
|
857
|
+
},
|
|
858
|
+
"file": {
|
|
859
|
+
"type": "string",
|
|
860
|
+
"description": "Caller file; narrows to one invocation."
|
|
861
|
+
},
|
|
862
|
+
"line": {
|
|
863
|
+
"type": "number",
|
|
864
|
+
"description": "Caller line; combined with file selects one invocation."
|
|
865
|
+
},
|
|
866
|
+
"limit": {
|
|
867
|
+
"type": "number",
|
|
868
|
+
"description": "Maximum invocations to return. Default 50, max 200."
|
|
869
|
+
}
|
|
870
|
+
},
|
|
871
|
+
"required": []
|
|
872
|
+
}
|
|
873
|
+
},
|
|
874
|
+
"registry": {
|
|
875
|
+
"name": "query_inline_instantiation",
|
|
876
|
+
"isWrite": false,
|
|
877
|
+
"isReadOnly": true,
|
|
878
|
+
"effect": "workspace_read",
|
|
879
|
+
"riskLevel": 0,
|
|
880
|
+
"concurrencyClass": "lsp-limited"
|
|
881
|
+
}
|
|
882
|
+
},
|
|
883
|
+
{
|
|
884
|
+
"tool": {
|
|
885
|
+
"name": "analyze_pdx_flow",
|
|
886
|
+
"description": "Static cost model and gameplay relations for a file or definition: traversals (every_*/while), pulse handlers, nested fan-out, and typed edges (tech prerequisites, special project events, megastructure upgrades). Relative weights only.",
|
|
887
|
+
"inputSchema": {
|
|
888
|
+
"type": "object",
|
|
889
|
+
"properties": {
|
|
890
|
+
"file": {
|
|
891
|
+
"type": "string",
|
|
892
|
+
"description": "Optional file path to analyze; when omitted a definitionId must be given."
|
|
893
|
+
},
|
|
894
|
+
"definitionId": {
|
|
895
|
+
"type": "string",
|
|
896
|
+
"description": "Optional exact definition ID; combined with file to scope the analysis."
|
|
897
|
+
},
|
|
898
|
+
"entityType": {
|
|
899
|
+
"type": "string",
|
|
900
|
+
"description": "Optional exact CWTools entity type; use with definitionId to disambiguate duplicate IDs."
|
|
901
|
+
},
|
|
902
|
+
"limit": {
|
|
903
|
+
"type": "number",
|
|
904
|
+
"description": "Maximum costs and relations returned per collection. Default 100, max 500."
|
|
905
|
+
}
|
|
906
|
+
},
|
|
907
|
+
"required": []
|
|
908
|
+
}
|
|
909
|
+
},
|
|
910
|
+
"registry": {
|
|
911
|
+
"name": "analyze_pdx_flow",
|
|
912
|
+
"isWrite": false,
|
|
913
|
+
"isReadOnly": true,
|
|
914
|
+
"effect": "workspace_read",
|
|
915
|
+
"riskLevel": 0,
|
|
916
|
+
"concurrencyClass": "lsp-limited"
|
|
917
|
+
}
|
|
918
|
+
},
|
|
919
|
+
{
|
|
920
|
+
"tool": {
|
|
921
|
+
"name": "compare_definition_with_vanilla",
|
|
922
|
+
"description": "Field-level diff of one definition against its vanilla counterpart: added, removed and modified fields with stable source locations. Accepts exact entityType + symbolId only; returns the resolved winner and never fabricates a conclusion when the winner is ambiguous. Use before editing any file that overrides vanilla.",
|
|
923
|
+
"inputSchema": {
|
|
924
|
+
"type": "object",
|
|
925
|
+
"properties": {
|
|
926
|
+
"entityType": {
|
|
927
|
+
"type": "string",
|
|
928
|
+
"description": "Exact CWTools type name (e.g. event, technology, ship_size)."
|
|
929
|
+
},
|
|
930
|
+
"symbolId": {
|
|
931
|
+
"type": "string",
|
|
932
|
+
"description": "Exact definition ID shared by workspace and vanilla candidates."
|
|
933
|
+
}
|
|
934
|
+
},
|
|
935
|
+
"required": [
|
|
936
|
+
"entityType",
|
|
937
|
+
"symbolId"
|
|
938
|
+
]
|
|
939
|
+
}
|
|
940
|
+
},
|
|
941
|
+
"registry": {
|
|
942
|
+
"name": "compare_definition_with_vanilla",
|
|
943
|
+
"isWrite": false,
|
|
944
|
+
"isReadOnly": true,
|
|
945
|
+
"effect": "workspace_read",
|
|
946
|
+
"riskLevel": 0,
|
|
947
|
+
"concurrencyClass": "lsp-limited"
|
|
948
|
+
}
|
|
949
|
+
},
|
|
831
950
|
{
|
|
832
951
|
"tool": {
|
|
833
952
|
"name": "query_localisation_index",
|
|
@@ -855,6 +974,26 @@ var require_mcpTools = __commonJS({
|
|
|
855
974
|
"type": "boolean",
|
|
856
975
|
"description": "Only applies to prefix/contains searches. Default false."
|
|
857
976
|
},
|
|
977
|
+
"includeDuplicates": {
|
|
978
|
+
"type": "boolean",
|
|
979
|
+
"description": "Include per-key duplicate groups with all occurrences (file/line), so duplicate keys are auditable instead of trusting the last write. Default false."
|
|
980
|
+
},
|
|
981
|
+
"compareLanguages": {
|
|
982
|
+
"type": "boolean",
|
|
983
|
+
"description": "Include true missing/extra key-set differences per language, independent of result truncation. Default false."
|
|
984
|
+
},
|
|
985
|
+
"referenceLanguage": {
|
|
986
|
+
"type": "string",
|
|
987
|
+
"description": "Reference language for missing/extra differences. Defaults to l_english when indexed."
|
|
988
|
+
},
|
|
989
|
+
"referenceStatus": {
|
|
990
|
+
"type": "boolean",
|
|
991
|
+
"description": "Include bounded LSP reference status and origin; dynamic keys remain uncertain."
|
|
992
|
+
},
|
|
993
|
+
"auditMode": {
|
|
994
|
+
"type": "boolean",
|
|
995
|
+
"description": "Include authoritative CWTools localisation diagnostics: completely missing script-referenced keys, inline/dynamic-key provenance, and localisation command/scope issues."
|
|
996
|
+
},
|
|
858
997
|
"limit": {
|
|
859
998
|
"type": "number",
|
|
860
999
|
"description": "Maximum entries to return. Default 20, max 100."
|
|
@@ -906,7 +1045,7 @@ var require_mcpTools = __commonJS({
|
|
|
906
1045
|
{
|
|
907
1046
|
"tool": {
|
|
908
1047
|
"name": "get_completion_at",
|
|
909
|
-
"description": "Get auto-completion suggestions and
|
|
1048
|
+
"description": "Get auto-completion suggestions and bounded context at a specific position through the active VS Code language provider. In Paradox projects, CWTools may enrich the result with game-aware scope and schema context.",
|
|
910
1049
|
"inputSchema": {
|
|
911
1050
|
"type": "object",
|
|
912
1051
|
"properties": {
|
|
@@ -1064,7 +1203,7 @@ var require_mcpTools = __commonJS({
|
|
|
1064
1203
|
{
|
|
1065
1204
|
"tool": {
|
|
1066
1205
|
"name": "query_references",
|
|
1067
|
-
"description": "Find
|
|
1206
|
+
"description": "Find references to an identifier through the active language provider, with a bounded workspace text-search fallback.",
|
|
1068
1207
|
"inputSchema": {
|
|
1069
1208
|
"type": "object",
|
|
1070
1209
|
"properties": {
|
|
@@ -3216,16 +3355,17 @@ var require_profile = __commonJS({
|
|
|
3216
3355
|
}
|
|
3217
3356
|
}
|
|
3218
3357
|
function isProjectProfile(value) {
|
|
3219
|
-
return !!value && typeof value === "object" && value.schemaVersion === 1 && typeof value.projectName === "string";
|
|
3358
|
+
return !!value && typeof value === "object" && (value.schemaVersion === 1 || value.schemaVersion === 2) && typeof value.projectName === "string";
|
|
3220
3359
|
}
|
|
3221
3360
|
function buildProfileSummary(profile) {
|
|
3222
3361
|
const dirs = profile.keyDirectories.filter((dir) => dir.exists).map((dir) => dir.path).slice(0, 8).join(", ") || "none";
|
|
3223
3362
|
const namespaces = Array.isArray(profile.identifiers.namespaces) ? profile.identifiers.namespaces.slice(0, 8).join(", ") || "none" : "none";
|
|
3224
3363
|
const languages = profile.localisation.languages.join(", ") || "unknown";
|
|
3364
|
+
const supportedVersion = typeof profile.modInfo?.supportedVersion === "string" ? ` (${profile.modInfo.supportedVersion})` : "";
|
|
3225
3365
|
return [
|
|
3226
3366
|
`Project: ${profile.projectName}`,
|
|
3227
3367
|
`Kind: ${profile.workspaceKind}`,
|
|
3228
|
-
`Game: ${profile.game.displayName}`,
|
|
3368
|
+
`Game: ${profile.game.displayName}${supportedVersion}`,
|
|
3229
3369
|
`Key dirs: ${dirs}`,
|
|
3230
3370
|
`Namespaces: ${namespaces}`,
|
|
3231
3371
|
`Localisation: ${languages} (${profile.localisation.encoding})`
|
|
@@ -3254,6 +3394,14 @@ var require_profile = __commonJS({
|
|
|
3254
3394
|
return profile.identifiers;
|
|
3255
3395
|
case "validation":
|
|
3256
3396
|
return profile.validation;
|
|
3397
|
+
case "compatibility":
|
|
3398
|
+
return {
|
|
3399
|
+
supportedVersion: profile.modInfo?.supportedVersion,
|
|
3400
|
+
remoteFileId: profile.modInfo?.remoteFileId,
|
|
3401
|
+
dependencies: profile.modInfo?.dependencies ?? [],
|
|
3402
|
+
vanillaCache: profile.validation?.vanillaCache,
|
|
3403
|
+
game: profile.game
|
|
3404
|
+
};
|
|
3257
3405
|
case "promptCards":
|
|
3258
3406
|
return profile.promptCards;
|
|
3259
3407
|
case "all":
|
|
@@ -3264,7 +3412,10 @@ var require_profile = __commonJS({
|
|
|
3264
3412
|
workspaceKind: profile.workspaceKind,
|
|
3265
3413
|
projectName: profile.projectName,
|
|
3266
3414
|
game: profile.game,
|
|
3415
|
+
supportedVersion: profile.modInfo?.supportedVersion,
|
|
3267
3416
|
generatedAt: profile.generatedAt,
|
|
3417
|
+
freshness: profile.freshness,
|
|
3418
|
+
warnings: profile.warnings ?? [],
|
|
3268
3419
|
efficiencyHints: profile.efficiencyHints
|
|
3269
3420
|
};
|
|
3270
3421
|
}
|
|
@@ -3297,7 +3448,7 @@ var require_profile = __commonJS({
|
|
|
3297
3448
|
source: "cwtools-shared",
|
|
3298
3449
|
error: {
|
|
3299
3450
|
code: "invalid_profile",
|
|
3300
|
-
message: "Project profile exists but is not schemaVersion 1."
|
|
3451
|
+
message: "Project profile exists but is not a valid schemaVersion 1 or 2 profile."
|
|
3301
3452
|
}
|
|
3302
3453
|
};
|
|
3303
3454
|
}
|
|
@@ -3382,21 +3533,13 @@ var require_knowledge = __commonJS({
|
|
|
3382
3533
|
exports2.queryProjectKnowledgeWithHost = queryProjectKnowledgeWithHost;
|
|
3383
3534
|
var path = __importStar(require("path"));
|
|
3384
3535
|
var KNOWLEDGE_DIR = path.join(".cwtools", "project", "knowledge");
|
|
3536
|
+
var CURRENT_KNOWLEDGE_SCHEMA_VERSION = 7;
|
|
3385
3537
|
function asRecord(value) {
|
|
3386
3538
|
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
3387
3539
|
}
|
|
3388
3540
|
function stringArray(value) {
|
|
3389
3541
|
return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
|
|
3390
3542
|
}
|
|
3391
|
-
function tokensFor(args) {
|
|
3392
|
-
return [args.intent ?? "", ...args.identifiers ?? [], ...args.entityTypes ?? []].join(" ").toLowerCase().match(/[@a-z0-9_.:-]{2,}/g)?.slice(0, 30) ?? [];
|
|
3393
|
-
}
|
|
3394
|
-
function score(value, tokens) {
|
|
3395
|
-
if (tokens.length === 0)
|
|
3396
|
-
return 1;
|
|
3397
|
-
const text = JSON.stringify(value).toLowerCase();
|
|
3398
|
-
return tokens.reduce((total, token) => total + (text.includes(token) ? 3 : 0), 0);
|
|
3399
|
-
}
|
|
3400
3543
|
async function readJson(host, filePath) {
|
|
3401
3544
|
const read = await host.filesystem.readTextFile(filePath);
|
|
3402
3545
|
if (!read.exists)
|
|
@@ -3408,19 +3551,9 @@ var require_knowledge = __commonJS({
|
|
|
3408
3551
|
}
|
|
3409
3552
|
}
|
|
3410
3553
|
async function queryProjectKnowledgeWithHost(host, args = {}) {
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
if (!manifest) {
|
|
3415
|
-
const legacyRoot = path.join(host.workspaceRoot, ".cwtools-ai", "project", "knowledge");
|
|
3416
|
-
const legacyManifestPath = path.join(legacyRoot, "manifest.json");
|
|
3417
|
-
const legacyManifest = await readJson(host, legacyManifestPath);
|
|
3418
|
-
if (legacyManifest) {
|
|
3419
|
-
root = legacyRoot;
|
|
3420
|
-
manifestPath = legacyManifestPath;
|
|
3421
|
-
manifest = legacyManifest;
|
|
3422
|
-
}
|
|
3423
|
-
}
|
|
3554
|
+
const root = path.join(host.workspaceRoot, KNOWLEDGE_DIR);
|
|
3555
|
+
const manifestPath = path.join(root, "manifest.json");
|
|
3556
|
+
const manifest = await readJson(host, manifestPath);
|
|
3424
3557
|
if (!manifest) {
|
|
3425
3558
|
return {
|
|
3426
3559
|
ok: false,
|
|
@@ -3437,8 +3570,29 @@ var require_knowledge = __commonJS({
|
|
|
3437
3570
|
}
|
|
3438
3571
|
};
|
|
3439
3572
|
}
|
|
3440
|
-
|
|
3441
|
-
|
|
3573
|
+
const database = asRecord(manifest.database);
|
|
3574
|
+
const foundSchemaVersion = Number(database.schemaVersion ?? manifest.schemaVersion) || 0;
|
|
3575
|
+
if (Number(manifest.schemaVersion) !== CURRENT_KNOWLEDGE_SCHEMA_VERSION || foundSchemaVersion !== CURRENT_KNOWLEDGE_SCHEMA_VERSION) {
|
|
3576
|
+
return {
|
|
3577
|
+
ok: false,
|
|
3578
|
+
status: "stale",
|
|
3579
|
+
source: "cwtools-project-knowledge-sqlite",
|
|
3580
|
+
error: {
|
|
3581
|
+
code: "knowledge_schema_obsolete",
|
|
3582
|
+
message: `Project knowledge schema V${foundSchemaVersion} is obsolete. Rebuild it with the current V${CURRENT_KNOWLEDGE_SCHEMA_VERSION} extension.`
|
|
3583
|
+
},
|
|
3584
|
+
data: {
|
|
3585
|
+
status: "stale",
|
|
3586
|
+
manifestPath,
|
|
3587
|
+
rebuildRequired: true,
|
|
3588
|
+
foundSchemaVersion,
|
|
3589
|
+
currentSchemaVersion: CURRENT_KNOWLEDGE_SCHEMA_VERSION,
|
|
3590
|
+
staleReasons: ["schema_version_obsolete"],
|
|
3591
|
+
_hint: "Run /init or reopen the project and wait for the automatic full rebuild. Old database schemas are not queried."
|
|
3592
|
+
}
|
|
3593
|
+
};
|
|
3594
|
+
}
|
|
3595
|
+
{
|
|
3442
3596
|
const relativeDatabasePath = typeof database.path === "string" && database.path.trim() ? database.path : "knowledge.sqlite";
|
|
3443
3597
|
const databasePath = path.resolve(root, relativeDatabasePath);
|
|
3444
3598
|
const relative = path.relative(root, databasePath);
|
|
@@ -3463,74 +3617,22 @@ var require_knowledge = __commonJS({
|
|
|
3463
3617
|
data: { manifestPath, databasePath }
|
|
3464
3618
|
};
|
|
3465
3619
|
}
|
|
3466
|
-
const
|
|
3467
|
-
const
|
|
3468
|
-
const
|
|
3469
|
-
const partial =
|
|
3620
|
+
const manifestStatus = String(manifest.status ?? "stale");
|
|
3621
|
+
const staleReasons = stringArray(manifest.staleReasons);
|
|
3622
|
+
const ready = String(result.status ?? manifestStatus) === "ready" && manifestStatus === "ready" && staleReasons.length === 0;
|
|
3623
|
+
const partial = staleReasons.length === 0 && (String(result.status ?? manifestStatus) === "partial" || manifestStatus === "partial");
|
|
3470
3624
|
return {
|
|
3471
3625
|
ok: true,
|
|
3472
|
-
status:
|
|
3626
|
+
status: ready ? "ready" : partial ? "partial" : "stale",
|
|
3473
3627
|
source: "cwtools-project-knowledge-sqlite",
|
|
3474
3628
|
data: {
|
|
3475
3629
|
...result,
|
|
3476
|
-
status:
|
|
3630
|
+
status: ready ? "ready" : partial ? "partial" : "stale",
|
|
3477
3631
|
manifestPath,
|
|
3478
|
-
staleReasons
|
|
3632
|
+
staleReasons
|
|
3479
3633
|
}
|
|
3480
3634
|
};
|
|
3481
3635
|
}
|
|
3482
|
-
const manifestDomains = stringArray(manifest.domains);
|
|
3483
|
-
const domains = (args.domains?.length ? args.domains : manifestDomains).map((value) => value.trim().toLowerCase()).filter(Boolean).slice(0, 12);
|
|
3484
|
-
const tokens = tokensFor(args);
|
|
3485
|
-
const limit = Math.max(1, Math.min(Number(args.limit ?? 80) || 80, 300));
|
|
3486
|
-
const evidence = [];
|
|
3487
|
-
const capabilities = [];
|
|
3488
|
-
for (const domain of domains) {
|
|
3489
|
-
const capability = await readJson(host, path.join(root, "capabilities", `${domain}.json`));
|
|
3490
|
-
if (!capability)
|
|
3491
|
-
continue;
|
|
3492
|
-
capabilities.push({ domain, summary: capability.summary, evidencePolicy: capability.evidencePolicy });
|
|
3493
|
-
const candidates = [];
|
|
3494
|
-
if (Array.isArray(capability.definitions))
|
|
3495
|
-
candidates.push(...capability.definitions.map(asRecord));
|
|
3496
|
-
if (args.includeProjectPatterns !== false && Array.isArray(capability.projectExamples))
|
|
3497
|
-
candidates.push(...capability.projectExamples.map(asRecord));
|
|
3498
|
-
if (args.includeVanillaArchetypes !== false && Array.isArray(capability.vanillaArchetypes))
|
|
3499
|
-
candidates.push(...capability.vanillaArchetypes.map(asRecord));
|
|
3500
|
-
if (args.includeTopology !== false) {
|
|
3501
|
-
const topology = asRecord(capability.topology);
|
|
3502
|
-
if (Array.isArray(topology.edges))
|
|
3503
|
-
candidates.push(...topology.edges.map(asRecord));
|
|
3504
|
-
}
|
|
3505
|
-
evidence.push(...candidates.map((item) => ({ ...item, domain, score: score(item, tokens) })).filter((item) => tokens.length === 0 || Number(item.score) > 0).sort((a, b) => Number(b.score) - Number(a.score)).slice(0, Math.max(5, Math.ceil(limit / Math.max(1, domains.length)))));
|
|
3506
|
-
}
|
|
3507
|
-
const unresolvedFile = args.includeUnresolved === false ? void 0 : await readJson(host, path.join(root, "unresolved.json"));
|
|
3508
|
-
const unresolved = Array.isArray(unresolvedFile?.entries) ? unresolvedFile.entries.map(asRecord).slice(0, 100) : [];
|
|
3509
|
-
const manifestStatus = String(manifest.status ?? "stale");
|
|
3510
|
-
const staleReasons = stringArray(manifest.staleReasons);
|
|
3511
|
-
const ready = manifestStatus === "ready" && staleReasons.length === 0;
|
|
3512
|
-
return {
|
|
3513
|
-
ok: true,
|
|
3514
|
-
status: ready ? "ready" : "stale",
|
|
3515
|
-
source: "cwtools-project-knowledge",
|
|
3516
|
-
data: {
|
|
3517
|
-
status: ready ? "ready" : "stale",
|
|
3518
|
-
manifestPath,
|
|
3519
|
-
generatedAt: manifest.generatedAt,
|
|
3520
|
-
game: manifest.game,
|
|
3521
|
-
graphVersion: manifest.graphVersion,
|
|
3522
|
-
staleReasons,
|
|
3523
|
-
domains,
|
|
3524
|
-
capabilities,
|
|
3525
|
-
evidence: evidence.slice(0, limit),
|
|
3526
|
-
unresolved,
|
|
3527
|
-
requiredNextChecks: [
|
|
3528
|
-
"Use query_cwt_schema/query_rules/query_scope for legality before writing.",
|
|
3529
|
-
"Use query_override_modes for target directories with vanilla definitions.",
|
|
3530
|
-
"Read exact source blocks before approving a complex blueprint."
|
|
3531
|
-
]
|
|
3532
|
-
}
|
|
3533
|
-
};
|
|
3534
3636
|
}
|
|
3535
3637
|
}
|
|
3536
3638
|
});
|
|
@@ -3711,6 +3813,9 @@ var require_names = __commonJS({
|
|
|
3711
3813
|
"query_project_knowledge",
|
|
3712
3814
|
"query_workspace_index",
|
|
3713
3815
|
"explore_pdx_project",
|
|
3816
|
+
"query_inline_instantiation",
|
|
3817
|
+
"analyze_pdx_flow",
|
|
3818
|
+
"compare_definition_with_vanilla",
|
|
3714
3819
|
"query_localisation_index",
|
|
3715
3820
|
"get_pdx_block",
|
|
3716
3821
|
"get_completion_at",
|
|
@@ -4753,17 +4858,81 @@ var require_toolHandlers = __commonJS({
|
|
|
4753
4858
|
args.maxEdges ?? 80,
|
|
4754
4859
|
args.includeMetadata !== false
|
|
4755
4860
|
], "Start the CWTools LSP process and wait for the game model to load before exploring the semantic graph.");
|
|
4861
|
+
case "analyze_pdx_flow": {
|
|
4862
|
+
const file = typeof args.file === "string" ? args.file.trim() : "";
|
|
4863
|
+
const definitionId = typeof args.definitionId === "string" ? args.definitionId.trim() : "";
|
|
4864
|
+
if (!file && !definitionId) {
|
|
4865
|
+
return {
|
|
4866
|
+
ok: false,
|
|
4867
|
+
status: "error",
|
|
4868
|
+
source: "cwtools-shared",
|
|
4869
|
+
error: {
|
|
4870
|
+
code: "invalid_arguments",
|
|
4871
|
+
message: "analyze_pdx_flow requires a file or a definitionId."
|
|
4872
|
+
}
|
|
4873
|
+
};
|
|
4874
|
+
}
|
|
4875
|
+
return executeLspTool(host, "cwtools.ai.analyzePdxFlow", [{
|
|
4876
|
+
...file ? { file } : {},
|
|
4877
|
+
...definitionId ? { definitionId } : {},
|
|
4878
|
+
...typeof args.entityType === "string" && args.entityType.trim() ? { entityType: args.entityType.trim() } : {},
|
|
4879
|
+
limit: Math.max(1, Math.min(Number(args.limit ?? 100) || 100, 500))
|
|
4880
|
+
}], "Start the CWTools LSP process and wait for the game model to load before analyzing flow cost and gameplay relations.");
|
|
4881
|
+
}
|
|
4882
|
+
case "compare_definition_with_vanilla": {
|
|
4883
|
+
if (typeof args.entityType !== "string" || typeof args.symbolId !== "string" || !args.entityType.trim() || !args.symbolId.trim()) {
|
|
4884
|
+
return {
|
|
4885
|
+
ok: false,
|
|
4886
|
+
status: "error",
|
|
4887
|
+
source: "cwtools-shared",
|
|
4888
|
+
error: {
|
|
4889
|
+
code: "invalid_arguments",
|
|
4890
|
+
message: "compare_definition_with_vanilla requires entityType and symbolId."
|
|
4891
|
+
}
|
|
4892
|
+
};
|
|
4893
|
+
}
|
|
4894
|
+
return executeLspTool(host, "cwtools.ai.compareDefinitionWithVanilla", [args.entityType.trim(), args.symbolId.trim()], "Start the CWTools LSP process and wait for the game model to load before comparing the definition with vanilla.");
|
|
4895
|
+
}
|
|
4896
|
+
case "query_inline_instantiation": {
|
|
4897
|
+
const template = typeof args.template === "string" ? args.template.trim() : "";
|
|
4898
|
+
const file = typeof args.file === "string" ? args.file.trim() : "";
|
|
4899
|
+
if (!template && !file) {
|
|
4900
|
+
return {
|
|
4901
|
+
ok: false,
|
|
4902
|
+
status: "error",
|
|
4903
|
+
source: "cwtools-shared",
|
|
4904
|
+
error: {
|
|
4905
|
+
code: "invalid_arguments",
|
|
4906
|
+
message: "query_inline_instantiation requires a template path or a caller file (optionally with line)."
|
|
4907
|
+
}
|
|
4908
|
+
};
|
|
4909
|
+
}
|
|
4910
|
+
return executeLspTool(host, "cwtools.ai.exploreInlineGraph", [{
|
|
4911
|
+
...template ? { template } : {},
|
|
4912
|
+
...file ? { file } : {},
|
|
4913
|
+
...Number.isInteger(args.line) ? { line: Number(args.line) } : {},
|
|
4914
|
+
limit: Math.max(1, Math.min(Number(args.limit ?? 50) || 50, 200))
|
|
4915
|
+
}], "Start the CWTools LSP process and wait for the game model to load before resolving the inline template instantiation.");
|
|
4916
|
+
}
|
|
4756
4917
|
case "query_localisation_index": {
|
|
4757
4918
|
if (!host.indexing) {
|
|
4758
4919
|
return (0, schema_1.toolUnavailable)(name, "Localisation index is not available in this host.", [
|
|
4759
4920
|
"Wire an LSP index command or a thin Node index before using this tool for localisation evidence."
|
|
4760
4921
|
]);
|
|
4761
4922
|
}
|
|
4923
|
+
const data = await host.indexing.queryLocalisation(args);
|
|
4924
|
+
const semanticAudit = args.auditMode === true ? await executeLspTool(host, "cwtools.ai.queryLocalisationAudit", [{
|
|
4925
|
+
...typeof args.key === "string" ? { key: args.key } : {},
|
|
4926
|
+
prefix: args.prefix === true,
|
|
4927
|
+
contains: args.contains === true,
|
|
4928
|
+
caseSensitive: args.caseSensitive === true,
|
|
4929
|
+
limit: Math.max(1, Math.min(Number(args.limit ?? 100) || 100, 500))
|
|
4930
|
+
}], "Start the CWTools LSP process and wait for localisation validation before requesting auditMode.") : void 0;
|
|
4762
4931
|
return {
|
|
4763
4932
|
ok: true,
|
|
4764
4933
|
status: "ready",
|
|
4765
4934
|
source: "cwtools-index",
|
|
4766
|
-
data:
|
|
4935
|
+
data: semanticAudit ? { ...data, semanticAudit } : data
|
|
4767
4936
|
};
|
|
4768
4937
|
}
|
|
4769
4938
|
case "get_diagnostics": {
|
|
@@ -46446,16 +46615,8 @@ var require_resources = __commonJS({
|
|
|
46446
46615
|
};
|
|
46447
46616
|
}
|
|
46448
46617
|
case "cwtools://project/knowledge-manifest": {
|
|
46449
|
-
|
|
46450
|
-
|
|
46451
|
-
if (!read.exists) {
|
|
46452
|
-
const legacyPath = path.join(host.workspaceRoot, ".cwtools-ai", "project", "knowledge", "manifest.json");
|
|
46453
|
-
const legacyRead = await host.filesystem.readTextFile(legacyPath);
|
|
46454
|
-
if (legacyRead.exists) {
|
|
46455
|
-
manifestPath = legacyPath;
|
|
46456
|
-
read = legacyRead;
|
|
46457
|
-
}
|
|
46458
|
-
}
|
|
46618
|
+
const manifestPath = path.join(host.workspaceRoot, ".cwtools", "project", "knowledge", "manifest.json");
|
|
46619
|
+
const read = await host.filesystem.readTextFile(manifestPath);
|
|
46459
46620
|
return read.exists ? JSON.parse(read.content) : {
|
|
46460
46621
|
status: "missing",
|
|
46461
46622
|
manifestPath,
|
package/dist/mcp/resources.js
CHANGED
|
@@ -121,16 +121,8 @@ async function readResourceData(host, uri) {
|
|
|
121
121
|
};
|
|
122
122
|
}
|
|
123
123
|
case 'cwtools://project/knowledge-manifest': {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
if (!read.exists) {
|
|
127
|
-
const legacyPath = path.join(host.workspaceRoot, '.cwtools-ai', 'project', 'knowledge', 'manifest.json');
|
|
128
|
-
const legacyRead = await host.filesystem.readTextFile(legacyPath);
|
|
129
|
-
if (legacyRead.exists) {
|
|
130
|
-
manifestPath = legacyPath;
|
|
131
|
-
read = legacyRead;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
124
|
+
const manifestPath = path.join(host.workspaceRoot, '.cwtools', 'project', 'knowledge', 'manifest.json');
|
|
125
|
+
const read = await host.filesystem.readTextFile(manifestPath);
|
|
134
126
|
return read.exists
|
|
135
127
|
? JSON.parse(read.content)
|
|
136
128
|
: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cwtools-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Read-only MCP server exposing CWTools Paradox/Stellaris semantic tools to external agents",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
39
39
|
"chokidar": "^4.0.3",
|
|
40
|
-
"cwtools-shared": "0.
|
|
40
|
+
"cwtools-shared": "0.2.0",
|
|
41
41
|
"vscode-jsonrpc": "^8.2.0"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|