rbxstudio-mcp 2.3.2 → 2.4.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 (175) hide show
  1. package/README.md +67 -14
  2. package/dist/__tests__/bridge-service.test.js +25 -13
  3. package/dist/__tests__/bridge-service.test.js.map +1 -1
  4. package/dist/__tests__/bridge-session.test.d.ts +2 -0
  5. package/dist/__tests__/bridge-session.test.d.ts.map +1 -0
  6. package/dist/__tests__/bridge-session.test.js +171 -0
  7. package/dist/__tests__/bridge-session.test.js.map +1 -0
  8. package/dist/__tests__/chunker.test.d.ts +2 -0
  9. package/dist/__tests__/chunker.test.d.ts.map +1 -0
  10. package/dist/__tests__/chunker.test.js +201 -0
  11. package/dist/__tests__/chunker.test.js.map +1 -0
  12. package/dist/__tests__/docs-core.test.d.ts +2 -0
  13. package/dist/__tests__/docs-core.test.d.ts.map +1 -0
  14. package/dist/__tests__/docs-core.test.js +137 -0
  15. package/dist/__tests__/docs-core.test.js.map +1 -0
  16. package/dist/__tests__/docs-fetcher.test.d.ts +2 -0
  17. package/dist/__tests__/docs-fetcher.test.d.ts.map +1 -0
  18. package/dist/__tests__/docs-fetcher.test.js +173 -0
  19. package/dist/__tests__/docs-fetcher.test.js.map +1 -0
  20. package/dist/__tests__/helpers.d.ts +8 -0
  21. package/dist/__tests__/helpers.d.ts.map +1 -0
  22. package/dist/__tests__/helpers.js +23 -0
  23. package/dist/__tests__/helpers.js.map +1 -0
  24. package/dist/__tests__/http-routes.test.d.ts +2 -0
  25. package/dist/__tests__/http-routes.test.d.ts.map +1 -0
  26. package/dist/__tests__/http-routes.test.js +233 -0
  27. package/dist/__tests__/http-routes.test.js.map +1 -0
  28. package/dist/__tests__/http-server.test.js +13 -6
  29. package/dist/__tests__/http-server.test.js.map +1 -1
  30. package/dist/__tests__/integration.test.js +9 -4
  31. package/dist/__tests__/integration.test.js.map +1 -1
  32. package/dist/__tests__/semantic-search.test.d.ts +2 -0
  33. package/dist/__tests__/semantic-search.test.d.ts.map +1 -0
  34. package/dist/__tests__/semantic-search.test.js +202 -0
  35. package/dist/__tests__/semantic-search.test.js.map +1 -0
  36. package/dist/__tests__/smoke.test.js +7 -3
  37. package/dist/__tests__/smoke.test.js.map +1 -1
  38. package/dist/__tests__/studio-client.test.d.ts +2 -0
  39. package/dist/__tests__/studio-client.test.d.ts.map +1 -0
  40. package/dist/__tests__/studio-client.test.js +25 -0
  41. package/dist/__tests__/studio-client.test.js.map +1 -0
  42. package/dist/__tests__/tool-nudges.test.d.ts +2 -0
  43. package/dist/__tests__/tool-nudges.test.d.ts.map +1 -0
  44. package/dist/__tests__/tool-nudges.test.js +60 -0
  45. package/dist/__tests__/tool-nudges.test.js.map +1 -0
  46. package/dist/__tests__/tool-registry.test.d.ts +2 -0
  47. package/dist/__tests__/tool-registry.test.d.ts.map +1 -0
  48. package/dist/__tests__/tool-registry.test.js +365 -0
  49. package/dist/__tests__/tool-registry.test.js.map +1 -0
  50. package/dist/__tests__/tools-bridge.test.d.ts +2 -0
  51. package/dist/__tests__/tools-bridge.test.d.ts.map +1 -0
  52. package/dist/__tests__/tools-bridge.test.js +396 -0
  53. package/dist/__tests__/tools-bridge.test.js.map +1 -0
  54. package/dist/__tests__/tools-docs.test.d.ts +2 -0
  55. package/dist/__tests__/tools-docs.test.d.ts.map +1 -0
  56. package/dist/__tests__/tools-docs.test.js +112 -0
  57. package/dist/__tests__/tools-docs.test.js.map +1 -0
  58. package/dist/__tests__/tools-guards.test.d.ts +2 -0
  59. package/dist/__tests__/tools-guards.test.d.ts.map +1 -0
  60. package/dist/__tests__/tools-guards.test.js +131 -0
  61. package/dist/__tests__/tools-guards.test.js.map +1 -0
  62. package/dist/__tests__/tools-runtime.test.d.ts +2 -0
  63. package/dist/__tests__/tools-runtime.test.d.ts.map +1 -0
  64. package/dist/__tests__/tools-runtime.test.js +214 -0
  65. package/dist/__tests__/tools-runtime.test.js.map +1 -0
  66. package/dist/__tests__/tools-visual.test.d.ts +2 -0
  67. package/dist/__tests__/tools-visual.test.d.ts.map +1 -0
  68. package/dist/__tests__/tools-visual.test.js +149 -0
  69. package/dist/__tests__/tools-visual.test.js.map +1 -0
  70. package/dist/bridge-service.d.ts +99 -12
  71. package/dist/bridge-service.d.ts.map +1 -1
  72. package/dist/bridge-service.js +238 -21
  73. package/dist/bridge-service.js.map +1 -1
  74. package/dist/docs/cache.d.ts +50 -0
  75. package/dist/docs/cache.d.ts.map +1 -0
  76. package/dist/docs/cache.js +123 -0
  77. package/dist/docs/cache.js.map +1 -0
  78. package/dist/docs/embeddings/chunker.d.ts +120 -0
  79. package/dist/docs/embeddings/chunker.d.ts.map +1 -0
  80. package/dist/docs/embeddings/chunker.js +395 -0
  81. package/dist/docs/embeddings/chunker.js.map +1 -0
  82. package/dist/docs/embeddings/embedder.d.ts +41 -0
  83. package/dist/docs/embeddings/embedder.d.ts.map +1 -0
  84. package/dist/docs/embeddings/embedder.js +113 -0
  85. package/dist/docs/embeddings/embedder.js.map +1 -0
  86. package/dist/docs/embeddings/index.d.ts +102 -0
  87. package/dist/docs/embeddings/index.d.ts.map +1 -0
  88. package/dist/docs/embeddings/index.js +250 -0
  89. package/dist/docs/embeddings/index.js.map +1 -0
  90. package/dist/docs/embeddings/manager.d.ts +68 -0
  91. package/dist/docs/embeddings/manager.d.ts.map +1 -0
  92. package/dist/docs/embeddings/manager.js +97 -0
  93. package/dist/docs/embeddings/manager.js.map +1 -0
  94. package/dist/docs/fetcher.d.ts +29 -0
  95. package/dist/docs/fetcher.d.ts.map +1 -0
  96. package/dist/docs/fetcher.js +244 -0
  97. package/dist/docs/fetcher.js.map +1 -0
  98. package/dist/docs/reference.d.ts +37 -0
  99. package/dist/docs/reference.d.ts.map +1 -0
  100. package/dist/docs/reference.js +108 -0
  101. package/dist/docs/reference.js.map +1 -0
  102. package/dist/docs/search.d.ts +194 -0
  103. package/dist/docs/search.d.ts.map +1 -0
  104. package/dist/docs/search.js +733 -0
  105. package/dist/docs/search.js.map +1 -0
  106. package/dist/http-server.d.ts.map +1 -1
  107. package/dist/http-server.js +52 -5
  108. package/dist/http-server.js.map +1 -1
  109. package/dist/index.d.ts +8 -9
  110. package/dist/index.d.ts.map +1 -1
  111. package/dist/index.js +35 -1035
  112. package/dist/index.js.map +1 -1
  113. package/dist/instructions.d.ts +15 -0
  114. package/dist/instructions.d.ts.map +1 -0
  115. package/dist/instructions.js +26 -0
  116. package/dist/instructions.js.map +1 -0
  117. package/dist/tools/defs/attributes.d.ts +6 -0
  118. package/dist/tools/defs/attributes.d.ts.map +1 -0
  119. package/dist/tools/defs/attributes.js +85 -0
  120. package/dist/tools/defs/attributes.js.map +1 -0
  121. package/dist/tools/defs/docs.d.ts +17 -0
  122. package/dist/tools/defs/docs.d.ts.map +1 -0
  123. package/dist/tools/defs/docs.js +151 -0
  124. package/dist/tools/defs/docs.js.map +1 -0
  125. package/dist/tools/defs/execute.d.ts +6 -0
  126. package/dist/tools/defs/execute.d.ts.map +1 -0
  127. package/dist/tools/defs/execute.js +21 -0
  128. package/dist/tools/defs/execute.js.map +1 -0
  129. package/dist/tools/defs/inspection.d.ts +7 -0
  130. package/dist/tools/defs/inspection.d.ts.map +1 -0
  131. package/dist/tools/defs/inspection.js +202 -0
  132. package/dist/tools/defs/inspection.js.map +1 -0
  133. package/dist/tools/defs/objects.d.ts +6 -0
  134. package/dist/tools/defs/objects.d.ts.map +1 -0
  135. package/dist/tools/defs/objects.js +111 -0
  136. package/dist/tools/defs/objects.js.map +1 -0
  137. package/dist/tools/defs/properties.d.ts +6 -0
  138. package/dist/tools/defs/properties.d.ts.map +1 -0
  139. package/dist/tools/defs/properties.js +71 -0
  140. package/dist/tools/defs/properties.js.map +1 -0
  141. package/dist/tools/defs/runtime.d.ts +6 -0
  142. package/dist/tools/defs/runtime.d.ts.map +1 -0
  143. package/dist/tools/defs/runtime.js +145 -0
  144. package/dist/tools/defs/runtime.js.map +1 -0
  145. package/dist/tools/defs/scripts.d.ts +18 -0
  146. package/dist/tools/defs/scripts.d.ts.map +1 -0
  147. package/dist/tools/defs/scripts.js +163 -0
  148. package/dist/tools/defs/scripts.js.map +1 -0
  149. package/dist/tools/defs/tags.d.ts +6 -0
  150. package/dist/tools/defs/tags.d.ts.map +1 -0
  151. package/dist/tools/defs/tags.js +74 -0
  152. package/dist/tools/defs/tags.js.map +1 -0
  153. package/dist/tools/defs/visual.d.ts +7 -0
  154. package/dist/tools/defs/visual.d.ts.map +1 -0
  155. package/dist/tools/defs/visual.js +208 -0
  156. package/dist/tools/defs/visual.js.map +1 -0
  157. package/dist/tools/index.d.ts +101 -25
  158. package/dist/tools/index.d.ts.map +1 -1
  159. package/dist/tools/index.js +580 -63
  160. package/dist/tools/index.js.map +1 -1
  161. package/dist/tools/nudges.d.ts +25 -0
  162. package/dist/tools/nudges.d.ts.map +1 -0
  163. package/dist/tools/nudges.js +34 -0
  164. package/dist/tools/nudges.js.map +1 -0
  165. package/dist/tools/registry.d.ts +20 -0
  166. package/dist/tools/registry.d.ts.map +1 -0
  167. package/dist/tools/registry.js +65 -0
  168. package/dist/tools/registry.js.map +1 -0
  169. package/dist/tools/types.d.ts +24 -0
  170. package/dist/tools/types.d.ts.map +1 -0
  171. package/dist/tools/types.js +2 -0
  172. package/dist/tools/types.js.map +1 -0
  173. package/package.json +7 -6
  174. package/studio-plugin/MCPPlugin.rbxmx +3 -238
  175. package/studio-plugin/plugin.luau +2041 -365
@@ -0,0 +1,194 @@
1
+ /**
2
+ * Pure-JS regex search over the cached docs tree.
3
+ *
4
+ * Why not shell out to ripgrep?
5
+ * 1. We can't assume `rg` is on the user's PATH (npm package, no
6
+ * system-deps story).
7
+ * 2. The cached tree is small (~30MB, ~3k files). A naive
8
+ * Promise.all() walk + JS regex on each file finishes in ~50–
9
+ * 200ms cold-cache and ~10–40ms hot-cache, which is fine for an
10
+ * interactive tool call.
11
+ * 3. We get full control of result shape, context lines, and graceful
12
+ * ignore of binary garbage.
13
+ *
14
+ * If this ever becomes a bottleneck the obvious upgrade is an in-memory
15
+ * grep index keyed by 4-grams or similar — but YAGNI for now.
16
+ */
17
+ export interface SearchHit {
18
+ /** Doc path relative to the content root, e.g. "en-us/reference/engine/classes/Part.yaml". */
19
+ path: string;
20
+ /** 1-indexed line number inside the file. */
21
+ line: number;
22
+ /** The matching line (rstripped). */
23
+ text: string;
24
+ /** Optional surrounding lines, included only when contextLines > 0 (or token-AND mode). */
25
+ context?: {
26
+ line: number;
27
+ text: string;
28
+ }[];
29
+ /**
30
+ * Token-AND mode only: which tokens matched the anchor line itself.
31
+ * Useful for the model to see "this line has Motor6D, but C0 is in the
32
+ * surrounding context".
33
+ */
34
+ matchedTokens?: string[];
35
+ /**
36
+ * Hybrid mode only: aggregate score in [0, 1] used to rank this hit.
37
+ * Combines keyword token coverage and semantic similarity. Populated
38
+ * by `searchDocsHybrid`; absent in pure literal / token-AND modes.
39
+ */
40
+ score?: number;
41
+ /**
42
+ * Hybrid mode only: raw cosine similarity of the embedding of the
43
+ * passage containing this hit against the query embedding, in
44
+ * [-1, 1]. Useful for the model to gauge how "topical" the hit is.
45
+ */
46
+ semanticScore?: number;
47
+ }
48
+ export interface SearchOptions {
49
+ /** Restrict to a subdirectory of `content/` (e.g. "en-us/animation"). */
50
+ scope?: string;
51
+ /** File extensions to search (default ["md","yaml","yml"]). Pass without leading dot. */
52
+ extensions?: string[];
53
+ /** Treat `pattern` as a JS regex instead of a literal string. Default false. */
54
+ useRegex?: boolean;
55
+ /** Case-sensitive match. Default false. */
56
+ caseSensitive?: boolean;
57
+ /** Lines of context before/after each hit (like grep -C). Default 0. */
58
+ contextLines?: number;
59
+ /** Hard cap on hits returned. Default 200 — generous but bounded. */
60
+ maxHits?: number;
61
+ /**
62
+ * Token-AND mode: lines of slack on either side of the anchor in which
63
+ * every whitespace-separated token in the query must appear at least
64
+ * once. Default 3. Ignored when `useRegex: true` or the query is a
65
+ * single token (those fall back to literal substring search).
66
+ */
67
+ windowLines?: number;
68
+ /**
69
+ * Semantic rerank toggle. Defaults to true.
70
+ *
71
+ * When true AND the query is in token-AND mode (multi-token, not
72
+ * regex), the keyword hits are reranked by cosine similarity against
73
+ * a sentence-embedding index of the docs. This dramatically improves
74
+ * relevance for natural-language queries while preserving all the
75
+ * keyword guarantees (every returned hit still contains all tokens
76
+ * within `windowLines`).
77
+ *
78
+ * Set to false to force pure keyword mode — useful for deterministic
79
+ * tests or when the semantic index is unavailable / undesired.
80
+ *
81
+ * Has no effect in literal mode (single token, quoted phrase, regex)
82
+ * because those queries already have unambiguous ranking by file
83
+ * position.
84
+ */
85
+ semantic?: boolean;
86
+ }
87
+ export interface SearchSummary {
88
+ totalHits: number;
89
+ truncated: boolean;
90
+ hits: SearchHit[];
91
+ /** How many files were scanned (not skipped by extension/scope filters). */
92
+ filesScanned: number;
93
+ /** ms spent inside this call. */
94
+ durationMs: number;
95
+ /**
96
+ * "literal" = single-token / regex / single phrase.
97
+ * "token-and" = multi-token AND-match within `windowLines`.
98
+ * "hybrid" = token-AND filtering + semantic rerank.
99
+ */
100
+ mode: 'literal' | 'token-and' | 'hybrid';
101
+ /** Tokens we actually searched for in token-and / hybrid mode. */
102
+ tokens?: string[];
103
+ /**
104
+ * Hybrid mode only: whether the semantic index was actually used. False
105
+ * means we wanted to rerank but the index was unavailable (first call
106
+ * before build finished, model download failure, etc.) and we fell
107
+ * back to plain keyword ranking. Lets the caller decide whether to
108
+ * retry, warm the cache, or just accept keyword results.
109
+ */
110
+ semanticUsed?: boolean;
111
+ /**
112
+ * Hybrid mode only: whether the returned hits are guaranteed to
113
+ * contain every meaningful query token. True for the normal
114
+ * "keyword AND + semantic rerank" path. False when keyword filtering
115
+ * yielded zero candidates and we fell back to pure-semantic top-K
116
+ * over the chunk index — in that case the model should treat hits
117
+ * as "topically relevant" rather than "lexically matching".
118
+ */
119
+ keywordFiltered?: boolean;
120
+ }
121
+ /**
122
+ * Inputs passed to `searchDocs` *in addition to* the public options.
123
+ * Currently just the docs SHA so the hybrid path can locate the right
124
+ * vector index. Keeping this out of `SearchOptions` because it's
125
+ * server-internal — the LLM never sets it.
126
+ */
127
+ export interface InternalSearchInputs {
128
+ /** Docs cache SHA, used to load/build the semantic index. */
129
+ docsSha?: string;
130
+ }
131
+ /**
132
+ * Top-level entry point. Decides between literal (single-token / regex)
133
+ * and token-AND (multi-token, windowed) search and dispatches.
134
+ *
135
+ * Token-AND mode triggers when ALL of:
136
+ * - `useRegex: false` (or unset)
137
+ * - the tokenized query has 2+ tokens
138
+ *
139
+ * Why? Plain literal substring is "the docs say `Motor6D C0` somewhere?"
140
+ * which is almost never true (the docs use dotted/quoted forms like
141
+ * `Class.Motor6D.C0|C0`). Token-AND turns the query into "find lines
142
+ * where Motor6D and C0 are both nearby", which is what the model
143
+ * actually meant.
144
+ */
145
+ export declare function searchDocs(cacheDir: string, pattern: string, options?: SearchOptions, internal?: InternalSearchInputs): Promise<SearchSummary>;
146
+ /**
147
+ * Read a single doc file by its content-relative path.
148
+ *
149
+ * Two flavors of input are accepted to make the LLM-facing tool more
150
+ * forgiving:
151
+ * • "en-us/reference/engine/classes/Part.yaml" (canonical)
152
+ * • "Part" / "Part.yaml" — best-effort lookup under reference/engine
153
+ * (handled by `resolveReferenceDoc` in reference.ts, not here).
154
+ */
155
+ export declare function readDocFile(cacheDir: string, relPath: string): Promise<{
156
+ path: string;
157
+ bytes: number;
158
+ content: string;
159
+ } | null>;
160
+ /**
161
+ * List doc files / subdirectories under a given relative path.
162
+ *
163
+ * Returns a flat structured listing intended for an LLM to navigate
164
+ * (think `ls`, not `tree`).
165
+ *
166
+ * Paginated: the engine docs `classes/` directory has ~1000 YAMLs and
167
+ * blowing all of them into a single tool response is just expensive
168
+ * tokens for nothing. Pass `offset`/`limit` to page through; default
169
+ * limit is 100. The full count is reported as `totalEntries`.
170
+ */
171
+ export interface DocListing {
172
+ path: string;
173
+ /** Total number of children at this path (across all pages). */
174
+ totalEntries: number;
175
+ /** Page offset that produced `entries`. */
176
+ offset: number;
177
+ /** Page limit that produced `entries`. */
178
+ limit: number;
179
+ /** True if there are more entries beyond this page. */
180
+ truncated: boolean;
181
+ entries: {
182
+ name: string;
183
+ type: 'file' | 'dir';
184
+ size?: number;
185
+ }[];
186
+ }
187
+ export interface ListOptions {
188
+ /** Page offset (default 0). */
189
+ offset?: number;
190
+ /** Page size (default 100, max 1000). */
191
+ limit?: number;
192
+ }
193
+ export declare function listDocs(cacheDir: string, relPath?: string, options?: ListOptions): Promise<DocListing | null>;
194
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/docs/search.ts"],"names":[],"mappings":"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"}