cwtools-shared 0.1.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.
Files changed (53) hide show
  1. package/dist/generated/mcpTools.d.ts +1112 -0
  2. package/dist/generated/mcpTools.js +1247 -0
  3. package/dist/host/diagnostics.d.ts +41 -0
  4. package/dist/host/diagnostics.js +18 -0
  5. package/dist/host/filesystem.d.ts +18 -0
  6. package/dist/host/filesystem.js +2 -0
  7. package/dist/host/hostServices.d.ts +49 -0
  8. package/dist/host/hostServices.js +2 -0
  9. package/dist/host/indexing.d.ts +54 -0
  10. package/dist/host/indexing.js +2 -0
  11. package/dist/host/lsp.d.ts +8 -0
  12. package/dist/host/lsp.js +27 -0
  13. package/dist/host/readiness.d.ts +11 -0
  14. package/dist/host/readiness.js +71 -0
  15. package/dist/host/vanillaCache.d.ts +12 -0
  16. package/dist/host/vanillaCache.js +56 -0
  17. package/dist/host/vsCodeHostServices.d.ts +27 -0
  18. package/dist/host/vsCodeHostServices.js +30 -0
  19. package/dist/index.d.ts +25 -0
  20. package/dist/index.js +41 -0
  21. package/dist/knowledge/diagnosticRouting.d.ts +13 -0
  22. package/dist/knowledge/diagnosticRouting.js +57 -0
  23. package/dist/knowledge/gameKnowledge.d.ts +20 -0
  24. package/dist/knowledge/gameKnowledge.js +52 -0
  25. package/dist/knowledge/rules.d.ts +162 -0
  26. package/dist/knowledge/rules.js +1383 -0
  27. package/dist/knowledge/workflowHints.d.ts +11 -0
  28. package/dist/knowledge/workflowHints.js +31 -0
  29. package/dist/project/knowledge.d.ts +15 -0
  30. package/dist/project/knowledge.js +209 -0
  31. package/dist/project/profile.d.ts +45 -0
  32. package/dist/project/profile.js +177 -0
  33. package/dist/safety/localisation.d.ts +33 -0
  34. package/dist/safety/localisation.js +105 -0
  35. package/dist/safety/paths.d.ts +21 -0
  36. package/dist/safety/paths.js +122 -0
  37. package/dist/safety/writes.d.ts +3 -0
  38. package/dist/safety/writes.js +19 -0
  39. package/dist/tools/mcpSchema.d.ts +5 -0
  40. package/dist/tools/mcpSchema.js +19 -0
  41. package/dist/tools/names.d.ts +6 -0
  42. package/dist/tools/names.js +51 -0
  43. package/dist/tools/pdxBlock.d.ts +17 -0
  44. package/dist/tools/pdxBlock.js +140 -0
  45. package/dist/tools/registry.d.ts +10 -0
  46. package/dist/tools/registry.js +2 -0
  47. package/dist/tools/schema.d.ts +36 -0
  48. package/dist/tools/schema.js +21 -0
  49. package/dist/tools/symbols.d.ts +60 -0
  50. package/dist/tools/symbols.js +625 -0
  51. package/dist/tools/toolHandlers.d.ts +4 -0
  52. package/dist/tools/toolHandlers.js +291 -0
  53. package/package.json +24 -0
@@ -0,0 +1,291 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.defaultSharedToolDispatcher = void 0;
37
+ const path = __importStar(require("path"));
38
+ const diagnosticRouting_1 = require("../knowledge/diagnosticRouting");
39
+ const rules_1 = require("../knowledge/rules");
40
+ const profile_1 = require("../project/profile");
41
+ const knowledge_1 = require("../project/knowledge");
42
+ const localisation_1 = require("../safety/localisation");
43
+ const pdxBlock_1 = require("./pdxBlock");
44
+ const schema_1 = require("./schema");
45
+ const symbols_1 = require("./symbols");
46
+ function asRecord(value) {
47
+ return value && typeof value === 'object' && !Array.isArray(value)
48
+ ? value
49
+ : {};
50
+ }
51
+ async function executeLspTool(host, command, args, unavailableNextStep) {
52
+ const result = await host.lsp.executeCommand(command, args);
53
+ const record = asRecord(result);
54
+ const errorRecord = asRecord(record.error);
55
+ const unavailable = record.status === 'unavailable' || errorRecord.code === 'lsp_unavailable';
56
+ return {
57
+ ok: !unavailable,
58
+ status: unavailable ? 'unavailable' : 'ready',
59
+ source: 'cwtools-lsp',
60
+ data: result,
61
+ error: unavailable
62
+ ? {
63
+ code: String(errorRecord.code ?? 'lsp_unavailable'),
64
+ message: String(errorRecord.message ?? 'LSP command is unavailable.'),
65
+ }
66
+ : undefined,
67
+ nextSteps: unavailable ? [unavailableNextStep] : undefined,
68
+ };
69
+ }
70
+ const defaultSharedToolDispatcher = async (host, name, rawArgs) => {
71
+ const args = asRecord(rawArgs);
72
+ switch (name) {
73
+ case 'query_project_profile':
74
+ return (0, profile_1.queryProjectProfileWithHost)(host, args);
75
+ case 'query_project_knowledge':
76
+ return (0, knowledge_1.queryProjectKnowledgeWithHost)(host, args);
77
+ case 'query_workspace_index': {
78
+ if (!host.indexing) {
79
+ return (0, schema_1.toolUnavailable)(name, 'Workspace index is not available in this host.', [
80
+ 'Wire an LSP index command or a thin Node index before using this tool for semantic evidence.',
81
+ ]);
82
+ }
83
+ const data = await host.indexing.queryWorkspace(args);
84
+ const status = data.status === 'ready'
85
+ ? 'ready'
86
+ : data.status === 'partial'
87
+ ? 'partial'
88
+ : data.status === 'error'
89
+ ? 'error'
90
+ : data.status === 'unavailable'
91
+ ? 'unavailable'
92
+ : 'loading';
93
+ return {
94
+ ok: true,
95
+ status,
96
+ source: 'cwtools-index',
97
+ data,
98
+ };
99
+ }
100
+ case 'explore_pdx_project':
101
+ return executeLspTool(host, 'cwtools.ai.exploreProject', [
102
+ typeof args.query === 'string' ? args.query : '',
103
+ typeof args.file === 'string' && args.file ? toFileUri(args.file, host.workspaceRoot) : '',
104
+ typeof args.typeName === 'string' ? args.typeName : '',
105
+ args.exact === true,
106
+ args.depth ?? 1,
107
+ args.maxNodes ?? 30,
108
+ args.maxEdges ?? 80,
109
+ args.includeMetadata !== false,
110
+ ], 'Start the CWTools LSP process and wait for the game model to load before exploring the semantic graph.');
111
+ case 'query_localisation_index': {
112
+ if (!host.indexing) {
113
+ return (0, schema_1.toolUnavailable)(name, 'Localisation index is not available in this host.', [
114
+ 'Wire an LSP index command or a thin Node index before using this tool for localisation evidence.',
115
+ ]);
116
+ }
117
+ return {
118
+ ok: true,
119
+ status: 'ready',
120
+ source: 'cwtools-index',
121
+ data: await host.indexing.queryLocalisation(args),
122
+ };
123
+ }
124
+ case 'get_diagnostics':
125
+ {
126
+ const diagnostics = await host.diagnostics.getDiagnostics(args);
127
+ return {
128
+ ok: diagnostics.ok,
129
+ status: diagnostics.status === 'unavailable' ? 'unavailable' : diagnostics.status === 'stale' ? 'stale' : diagnostics.status === 'pending' ? 'loading' : 'ready',
130
+ source: 'cwtools-diagnostics',
131
+ data: diagnostics,
132
+ error: diagnostics.error,
133
+ };
134
+ }
135
+ case 'analyze_diagnostic_error':
136
+ return {
137
+ ok: true,
138
+ status: 'ready',
139
+ source: 'cwtools-knowledge',
140
+ data: (0, diagnosticRouting_1.analyzeDiagnosticKnowledge)({
141
+ code: typeof args.code === 'string' ? args.code : undefined,
142
+ message: typeof args.message === 'string' ? args.message : undefined,
143
+ }),
144
+ };
145
+ case 'write_localisation':
146
+ return (0, localisation_1.writeLocalisationWithHost)(host, {
147
+ filePath: String(args.filePath ?? args.file ?? ''),
148
+ language: typeof args.language === 'string' ? args.language : undefined,
149
+ entries: Array.isArray(args.entries) ? args.entries : [],
150
+ });
151
+ case 'get_completion_at':
152
+ return (0, symbols_1.getCompletionAtWithHost)(host, {
153
+ file: String(args.file ?? ''),
154
+ line: Number(args.line ?? 0),
155
+ column: Number(args.column ?? 0),
156
+ limit: typeof args.limit === 'number' ? args.limit : undefined,
157
+ });
158
+ case 'document_symbols':
159
+ return (0, symbols_1.documentSymbolsWithHost)(host, {
160
+ file: String(args.file ?? ''),
161
+ });
162
+ case 'workspace_symbols':
163
+ return (0, symbols_1.workspaceSymbolsWithHost)(host, {
164
+ query: String(args.query ?? ''),
165
+ limit: typeof args.limit === 'number' ? args.limit : undefined,
166
+ });
167
+ case 'query_definition':
168
+ return (0, symbols_1.queryDefinitionWithHost)(host, {
169
+ file: String(args.file ?? ''),
170
+ line: Number(args.line ?? 0),
171
+ column: Number(args.column ?? 0),
172
+ });
173
+ case 'query_definition_by_name':
174
+ return (0, symbols_1.queryDefinitionByNameWithHost)(host, {
175
+ symbolName: String(args.symbolName ?? ''),
176
+ });
177
+ case 'query_references':
178
+ return (0, symbols_1.queryReferencesWithHost)(host, {
179
+ identifier: String(args.identifier ?? ''),
180
+ file: typeof args.file === 'string' ? args.file : undefined,
181
+ limit: typeof args.limit === 'number' ? args.limit : undefined,
182
+ });
183
+ case 'query_scope':
184
+ return executeLspTool(host, 'cwtools.ai.getScopeAtPosition', [toFileUri(String(args.file ?? ''), host.workspaceRoot), args.line, args.column], 'Start the CWTools LSP process or connect this host to an existing language server.');
185
+ case 'query_types':
186
+ return executeLspTool(host, 'cwtools.ai.queryTypes', [args.typeName, args.filter ?? '', args.limit ?? 30, args.vanilla === true], 'Start the CWTools LSP process or connect this host to an existing language server.');
187
+ case 'query_rules':
188
+ return (0, rules_1.queryRulesWithHost)(host, {
189
+ category: String(args.category ?? 'trigger'),
190
+ name: typeof args.name === 'string' ? args.name : undefined,
191
+ scope: typeof args.scope === 'string' ? args.scope : undefined,
192
+ });
193
+ case 'query_cwt_schema':
194
+ return (0, rules_1.queryCwtSchemaWithHost)(host, {
195
+ target: typeof args.target === 'string' ? args.target : undefined,
196
+ file: typeof args.file === 'string' ? args.file : undefined,
197
+ directory: typeof args.directory === 'string' ? args.directory : undefined,
198
+ name: typeof args.name === 'string' ? args.name : undefined,
199
+ includeContent: args.includeContent === true,
200
+ limit: typeof args.limit === 'number' ? args.limit : undefined,
201
+ });
202
+ case 'search_rule_capabilities':
203
+ return (0, rules_1.searchRuleCapabilitiesWithHost)(host, {
204
+ intent: typeof args.intent === 'string' ? args.intent : undefined,
205
+ category: typeof args.category === 'string' ? args.category : undefined,
206
+ currentScope: typeof args.currentScope === 'string' ? args.currentScope : undefined,
207
+ desiredPushScope: typeof args.desiredPushScope === 'string' ? args.desiredPushScope : undefined,
208
+ limit: typeof args.limit === 'number' ? args.limit : undefined,
209
+ });
210
+ case 'explain_scope':
211
+ return (0, rules_1.explainScopeWithHost)(host, {
212
+ scope: String(args.scope ?? ''),
213
+ });
214
+ case 'parse_pdx_fragment':
215
+ return executeLspTool(host, 'cwtools.ai.parseFragment', [String(args.code ?? '')], 'Start the CWTools LSP process or connect this host to an existing language server.');
216
+ case 'query_scripted_effects':
217
+ return executeLspTool(host, 'cwtools.ai.queryScriptedEffects', [args.filter ?? '', args.limit ?? 50], 'Start the CWTools LSP process or connect this host to an existing language server.');
218
+ case 'query_scripted_triggers':
219
+ return executeLspTool(host, 'cwtools.ai.queryScriptedTriggers', [args.filter ?? '', args.limit ?? 50], 'Start the CWTools LSP process or connect this host to an existing language server.');
220
+ case 'query_enums':
221
+ return executeLspTool(host, 'cwtools.ai.queryEnums', [args.enumName ?? '', args.limit ?? 500], 'Start the CWTools LSP process or connect this host to an existing language server.');
222
+ case 'query_static_modifiers':
223
+ return executeLspTool(host, 'cwtools.ai.queryStaticModifiers', [args.filter ?? '', args.limit ?? 300], 'Start the CWTools LSP process or connect this host to an existing language server.');
224
+ case 'query_variables':
225
+ return executeLspTool(host, 'cwtools.ai.queryVariables', [args.filter ?? ''], 'Start the CWTools LSP process or connect this host to an existing language server.');
226
+ case 'get_entity_info':
227
+ return executeLspTool(host, 'cwtools.ai.getEntityInfo', [toFileUri(String(args.file ?? ''), host.workspaceRoot)], 'Start the CWTools LSP process or connect this host to an existing language server.');
228
+ case 'get_pdx_block':
229
+ return (0, pdxBlock_1.getPdxBlockWithHost)(host, {
230
+ file: String(args.file ?? ''),
231
+ symbol: String(args.symbol ?? ''),
232
+ });
233
+ // Shader knowledge tools: each LSP command takes a single JSON record
234
+ // argument and returns { ok, ... } / { ok: false, status: 'error', ... }.
235
+ case 'query_shader_symbol':
236
+ return executeLspTool(host, 'cwtools.ai.shader.symbols', [shaderRecord({
237
+ filter: typeof args.filter === 'string' ? args.filter : undefined,
238
+ kind: typeof args.kind === 'string' ? args.kind : undefined,
239
+ limit: typeof args.limit === 'number' ? args.limit : undefined,
240
+ cursor: typeof args.cursor === 'number' ? args.cursor : undefined,
241
+ })], 'Start the CWTools LSP process and wait for the shader model to load before querying shader symbols.');
242
+ case 'query_shader_compile_unit':
243
+ return executeLspTool(host, 'cwtools.ai.shader.compileUnit', [{ uri: toFileUri(String(args.file ?? ''), host.workspaceRoot) }], 'Start the CWTools LSP process and wait for the shader model to load before resolving compile units.');
244
+ case 'query_shader_platform_variants':
245
+ return executeLspTool(host, 'cwtools.ai.shader.variants', [{ uri: toFileUri(String(args.file ?? ''), host.workspaceRoot) }], 'Start the CWTools LSP process and wait for the shader model to load before comparing shader platform variants.');
246
+ case 'query_shader_callers':
247
+ return executeLspTool(host, 'cwtools.ai.shader.callers', [shaderRecord({
248
+ effectName: String(args.effectName ?? ''),
249
+ limit: typeof args.limit === 'number' ? args.limit : undefined,
250
+ })], 'Start the CWTools LSP process and wait for the shader model to load before querying Effect callers.');
251
+ case 'explain_shader_reachability':
252
+ return executeLspTool(host, 'cwtools.ai.shader.reachability', [typeof args.effectName === 'string' && args.effectName
253
+ ? { effectName: args.effectName }
254
+ : shaderRecord({
255
+ uri: toFileUri(String(args.file ?? ''), host.workspaceRoot),
256
+ limit: typeof args.limit === 'number' ? args.limit : undefined,
257
+ cursor: typeof args.cursor === 'number' ? args.cursor : undefined,
258
+ })], 'Start the CWTools LSP process and wait for the shader model to load before explaining Effect reachability.');
259
+ case 'validate_shader':
260
+ return executeLspTool(host, 'cwtools.ai.shader.validate', [{ uri: toFileUri(String(args.file ?? ''), host.workspaceRoot) }], 'Start the CWTools LSP process and wait for the shader model to load before validating shader files.');
261
+ case 'compare_shader_with_vanilla':
262
+ return executeLspTool(host, 'cwtools.ai.shader.compareVanilla', [typeof args.effectName === 'string' && args.effectName
263
+ ? { effectName: args.effectName }
264
+ : { uri: toFileUri(String(args.file ?? ''), host.workspaceRoot) }], 'Start the CWTools LSP process and wait for the shader model to load before comparing with vanilla.');
265
+ default:
266
+ return {
267
+ ok: false,
268
+ status: 'error',
269
+ source: 'cwtools-shared',
270
+ error: {
271
+ code: 'unknown_tool',
272
+ message: `Unknown MCP tool: ${name}`,
273
+ },
274
+ };
275
+ }
276
+ };
277
+ exports.defaultSharedToolDispatcher = defaultSharedToolDispatcher;
278
+ function toFileUri(filePath, workspaceRoot) {
279
+ const resolved = path.resolve(workspaceRoot, filePath).replace(/\\/g, '/');
280
+ const withLeadingSlash = resolved.startsWith('/') ? resolved : `/${resolved}`;
281
+ return `file://${encodeURI(withLeadingSlash).replace(/#/g, '%23')}`;
282
+ }
283
+ /** Drop undefined fields so the LSP command record only carries provided args. */
284
+ function shaderRecord(fields) {
285
+ const record = {};
286
+ for (const [key, value] of Object.entries(fields)) {
287
+ if (value !== undefined)
288
+ record[key] = value;
289
+ }
290
+ return record;
291
+ }
package/package.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "cwtools-shared",
3
+ "version": "0.1.0",
4
+ "description": "Shared protocol and tool contracts for the CWTools MCP server",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/Aa728848/cwtools-mcp.git"
9
+ },
10
+ "engines": {
11
+ "node": ">=18"
12
+ },
13
+ "main": "dist/index.js",
14
+ "types": "dist/index.d.ts",
15
+ "files": [
16
+ "dist",
17
+ "package.json"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsc -p tsconfig.json",
21
+ "prepack": "npm run build",
22
+ "test:contracts": "ts-mocha -p tsconfig.test.json \"src/test/**/*.test.ts\""
23
+ }
24
+ }