@el4cteo/rbx-studio-mcp 0.6.1 → 0.6.5

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 (47) hide show
  1. package/dist/index.js +4 -0
  2. package/dist/index.js.map +1 -1
  3. package/dist/tools/anim.js +159 -0
  4. package/dist/tools/anim.js.map +1 -0
  5. package/dist/tools/character.js +95 -5
  6. package/dist/tools/character.js.map +1 -1
  7. package/dist/tools/data.js +173 -0
  8. package/dist/tools/data.js.map +1 -0
  9. package/dist/tools/device.js +77 -7
  10. package/dist/tools/device.js.map +1 -1
  11. package/dist/tools/discover.js +80 -4
  12. package/dist/tools/discover.js.map +1 -1
  13. package/dist/tools/exec.js +48 -1
  14. package/dist/tools/exec.js.map +1 -1
  15. package/dist/tools/input.js +35 -9
  16. package/dist/tools/input.js.map +1 -1
  17. package/dist/tools/perf.js +74 -7
  18. package/dist/tools/perf.js.map +1 -1
  19. package/dist/tools/scripts.js +51 -3
  20. package/dist/tools/scripts.js.map +1 -1
  21. package/dist/tools/world.js +317 -44
  22. package/dist/tools/world.js.map +1 -1
  23. package/package.json +74 -74
  24. package/plugin/src/Commands.luau +622 -622
  25. package/plugin/src/Config.luau +65 -65
  26. package/plugin/src/Console.luau +1909 -1843
  27. package/plugin/src/Emulation.luau +172 -0
  28. package/plugin/src/Phrase.luau +164 -16
  29. package/plugin/src/Png.luau +8 -4
  30. package/plugin/src/Serialize.luau +499 -327
  31. package/plugin/src/Undo.luau +94 -6
  32. package/plugin/src/handlers/Anim.luau +897 -0
  33. package/plugin/src/handlers/Assets.luau +587 -352
  34. package/plugin/src/handlers/Capture.luau +155 -20
  35. package/plugin/src/handlers/Character.luau +823 -361
  36. package/plugin/src/handlers/Data.luau +539 -0
  37. package/plugin/src/handlers/Device.luau +394 -139
  38. package/plugin/src/handlers/Discover.luau +685 -363
  39. package/plugin/src/handlers/Geometry.luau +127 -0
  40. package/plugin/src/handlers/Perf.luau +227 -0
  41. package/plugin/src/handlers/Scripts.luau +673 -539
  42. package/plugin/src/handlers/Session.luau +3 -0
  43. package/plugin/src/handlers/Viewport.luau +268 -0
  44. package/plugin/src/handlers/World.luau +89 -15
  45. package/plugin/src/init.server.luau +879 -875
  46. package/scripts/build-plugin.mjs +20 -0
  47. package/scripts/check-plugin.mjs +171 -124
package/dist/index.js CHANGED
@@ -22,6 +22,8 @@ import { registerSessionTools } from "./tools/session.js";
22
22
  import { registerInputTools } from "./tools/input.js";
23
23
  import { registerDeviceTools } from "./tools/device.js";
24
24
  import { registerApiTools } from "./tools/api.js";
25
+ import { registerDataTools } from "./tools/data.js";
26
+ import { registerAnimTools } from "./tools/anim.js";
25
27
  import { registerResources } from "./resources.js";
26
28
  const VERSION = "0.3.5";
27
29
  function parsePort(argv) {
@@ -101,6 +103,8 @@ async function main() {
101
103
  registerInputTools(context);
102
104
  registerDeviceTools(context);
103
105
  registerApiTools(context);
106
+ registerDataTools(context);
107
+ registerAnimTools(context);
104
108
  registerTerrainTools(context);
105
109
  registerWorldTools(context);
106
110
  registerGenerateTools(context);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,159 @@
1
+ import { z } from "zod";
2
+ import { json, table, text, textOf } from "../lib/format.js";
3
+ import { defineTool } from "../lib/tool.js";
4
+ /** Downloads go to Roblox's asset servers, which are not always quick. */
5
+ const TIMEOUT_MS = 45_000;
6
+ export function registerAnimTools(context) {
7
+ const { bridge } = context;
8
+ defineTool(context, {
9
+ name: "animation",
10
+ title: "Read and build animations",
11
+ description: "Reads an animation's actual keyframes, and builds new ones that play " +
12
+ "immediately in the open Studio.\n\n" +
13
+ "Animations are the one part of a place no other tool can see. " +
14
+ "`inspect` on an Animation instance returns an asset id and stops there " +
15
+ "— the poses live on Roblox's servers. `read` downloads them, so you can " +
16
+ "answer 'how long is it', 'which joints does it move', and 'does it end " +
17
+ "where it started' without opening the Animation Editor and scrubbing.\n\n" +
18
+ "`read` takes an asset id, an rbxassetid:// string, or the path of an " +
19
+ "Animation instance in the place — whichever you already have. It reports " +
20
+ "which RIG the animation was made for, which is the thing most worth " +
21
+ "knowing: an R15 animation on an R6 character does nothing at all — no " +
22
+ "error, no movement — and the asset id gives no hint either way.\n\n" +
23
+ "`build` goes the other way: give it keyframes and it returns a content " +
24
+ "id you can put straight into an Animation's AnimationId. Nothing is " +
25
+ "uploaded and nothing is moderated — the id works in this Studio session " +
26
+ "and nowhere else, which makes it the right way to try an idea and the " +
27
+ "wrong way to ship one.\n\n" +
28
+ "`preview` puts an animation ONTO a rig in the open place and freezes it " +
29
+ "at a chosen moment, so `screenshot` can show you the pose. It works in " +
30
+ "edit mode — no playtest. Ask for several moments in turn to compare " +
31
+ "poses across the animation; the rig stays posed until `stop`.\n\n" +
32
+ "Poses are written the way a CFrame property is: \"0, 1, 0\" for a " +
33
+ "position, \"0, 1, 0 | 0, 45, 0\" to rotate as well.\n\n" +
34
+ "The id `build` returns is a bare hash, not an rbxassetid:// URL. Use it " +
35
+ "exactly as given — prefixing it stops it working.",
36
+ inputSchema: {
37
+ op: z
38
+ .enum(["read", "preview", "build", "stop"])
39
+ .default("read")
40
+ .describe("'read' downloads an existing animation, 'preview' poses a rig at one " +
41
+ "moment of it so you can screenshot it, 'build' makes a new one " +
42
+ "playable here, 'stop' clears a preview."),
43
+ assetId: z
44
+ .union([z.number(), z.string()])
45
+ .optional()
46
+ .describe('read only: animation asset id (12345), "rbxassetid://12345", or the ' +
47
+ 'path of an Animation instance ("Workspace.Rig.Animate.run").'),
48
+ keyframes: z
49
+ .array(z.object({
50
+ time: z.number().min(0).describe("Seconds from the start of the animation."),
51
+ name: z.string().optional().describe('Keyframe name, e.g. "Start" or a marker name.'),
52
+ poses: z
53
+ .record(z.string(), z.string())
54
+ .optional()
55
+ .describe('Joint name → CFrame, e.g. { "Right Arm": "0, 0.5, 0 | 0, 0, 45" }. ' +
56
+ "Joint names must match the rig's parts."),
57
+ }))
58
+ .max(200)
59
+ .optional()
60
+ .describe("build only: the keyframes, in any order — they are sorted by time."),
61
+ name: z.string().optional().describe("build only: name for the sequence."),
62
+ root: z
63
+ .string()
64
+ .optional()
65
+ .describe('build only: the rig part every pose hangs from. Defaults to "HumanoidRootPart", ' +
66
+ "which is right for an R15 or R6 character."),
67
+ priority: z
68
+ .enum(["Idle", "Movement", "Action", "Core"])
69
+ .optional()
70
+ .describe("build only: which animations this one plays over."),
71
+ loop: z.boolean().optional().describe("build only: whether it repeats."),
72
+ rig: z
73
+ .string()
74
+ .optional()
75
+ .describe('The model, e.g. "Workspace.Dummy". For preview/stop it is the rig to ' +
76
+ "pose, and needs a Humanoid or an AnimationController inside it. For " +
77
+ "`build` it is optional and is read for its joint layout — pass it for " +
78
+ "anything that is not a standard R6 or R15 character (a custom rig, a " +
79
+ "weapon, a door, a Blender import), or the poses may be attached in the " +
80
+ "wrong order and the animation will move nothing."),
81
+ at: z
82
+ .number()
83
+ .min(0)
84
+ .optional()
85
+ .describe("preview only: the moment to freeze on, in seconds. Ask for several " +
86
+ "in turn to compare poses across the animation."),
87
+ hold: z
88
+ .boolean()
89
+ .default(true)
90
+ .describe("preview only: freeze on that frame. Turn off to let it play, but then " +
91
+ "a screenshot catches whatever pose it happens to be in."),
92
+ studioId: z.string().optional().describe("Target Studio; omit for the active one."),
93
+ },
94
+ readOnly: false,
95
+ destructive: false,
96
+ }, async (args) => {
97
+ if (args.op === "preview" || args.op === "stop") {
98
+ if (!args.rig)
99
+ return text("preview needs a `rig` — the model to pose.");
100
+ const posed = await bridge.call("anim.preview", { op: args.op, rig: args.rig, assetId: args.assetId, at: args.at, hold: args.hold }, { studioId: args.studioId, timeoutMs: TIMEOUT_MS });
101
+ return json(posed);
102
+ }
103
+ if (args.op === "build") {
104
+ if (!args.keyframes || args.keyframes.length === 0) {
105
+ return text("build needs a non-empty `keyframes` array.");
106
+ }
107
+ const built = await bridge.call("anim.build", {
108
+ keyframes: args.keyframes,
109
+ name: args.name,
110
+ root: args.root,
111
+ rig: args.rig,
112
+ priority: args.priority,
113
+ loop: args.loop,
114
+ }, { studioId: args.studioId, timeoutMs: TIMEOUT_MS });
115
+ return json(built, "Set this as an Animation's AnimationId with `modify`, exactly as it appears " +
116
+ "— it is a bare hash, and adding rbxassetid:// in front of it stops it " +
117
+ "working. Local to this Studio session: not uploaded, gone on restart.\n\n" +
118
+ "`hierarchy` says which joint layout the poses were nested against — the " +
119
+ "rig you named, or the R6/R15 standard guessed from the joint names. " +
120
+ "Anything in `unmatchedJoints` is a name that layout does not contain: " +
121
+ "those poses were attached to the root and will almost certainly do " +
122
+ "nothing. Pass `rig` to fix it.");
123
+ }
124
+ if (args.assetId === undefined) {
125
+ return text("read needs an `assetId` — a number, an rbxassetid:// string, or a path to an Animation.");
126
+ }
127
+ const found = await bridge.call("anim.read", { assetId: args.assetId }, { studioId: args.studioId, timeoutMs: TIMEOUT_MS });
128
+ /*
129
+ * A summary first, then the timeline. The three facts at the top are what
130
+ * the question was, and burying them under forty rows of keyframes would
131
+ * make the tool technically complete and practically unreadable.
132
+ */
133
+ const lines = [
134
+ `${found.name ?? found.assetId} — ${found.rig} rig, ${found.duration}s, ` +
135
+ `${found.keyframeCount} keyframes, ${found.jointCount} joints moved`,
136
+ `Priority ${found.priority}${found.looping ? ", loops" : ", does not loop"}` +
137
+ (found.rigNote !== undefined ? ` — ${found.rigNote}` : ""),
138
+ "",
139
+ `Joints: ${found.joints.join(", ") || "none"}` +
140
+ (found.jointsSampled ? ` … and ${found.jointCount - found.joints.length} more` : ""),
141
+ ];
142
+ if (found.rig === "R6" || found.rig === "R15") {
143
+ lines.push("", `This is an ${found.rig} animation. It will do NOTHING on an ${found.rig === "R6" ? "R15" : "R6"} character — no error, no movement, because the joint names do not exist ` +
144
+ "on the other rig. Check the character's rig type before using it.");
145
+ }
146
+ if (found.looping && found.endsWhereItStarted === false) {
147
+ lines.push("", "WARNING: this animation loops, but these joints do not end where they " +
148
+ `started: ${(found.driftingJoints ?? []).join(", ")}. That is what a ` +
149
+ "visible jump at the loop point looks like.");
150
+ }
151
+ lines.push("", textOf(table(["index", "time", "name", "poseCount"], found.keyframes, {
152
+ more: found.truncated
153
+ ? `poses expanded for the first 40 keyframes only`
154
+ : undefined,
155
+ })));
156
+ return text(lines.join("\n"));
157
+ });
158
+ }
159
+ //# sourceMappingURL=anim.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anim.js","sourceRoot":"","sources":["../../src/tools/anim.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { json } from "../lib/format.js";
2
+ import { json, table, text, textOf } from "../lib/format.js";
3
3
  import { defineTool } from "../lib/tool.js";
4
4
  export function registerCharacterTools(context) {
5
5
  const { bridge } = context;
@@ -33,8 +33,9 @@ export function registerCharacterTools(context) {
33
33
  "use `playtest op=play`.",
34
34
  inputSchema: {
35
35
  op: z
36
- .enum(["moveTo", "act", "state"])
37
- .describe("'moveTo' walks somewhere, 'act' performs an action, 'state' only reports."),
36
+ .enum(["moveTo", "path", "act", "state"])
37
+ .describe("'moveTo' walks somewhere, 'path' checks a route without walking it, " +
38
+ "'act' performs an action, 'state' only reports."),
38
39
  to: z
39
40
  .string()
40
41
  .optional()
@@ -43,6 +44,46 @@ export function registerCharacterTools(context) {
43
44
  .string()
44
45
  .optional()
45
46
  .describe("moveTo only: walk to this instance instead of a coordinate."),
47
+ from: z
48
+ .string()
49
+ .optional()
50
+ .describe('path only: where the route starts, e.g. "0, 5, 0". Defaults to the character.'),
51
+ fromPath: z
52
+ .string()
53
+ .optional()
54
+ .describe('path only: an instance to start from, e.g. "Workspace.SpawnLocation".'),
55
+ toPath: z
56
+ .string()
57
+ .optional()
58
+ .describe("path only: an instance to end at instead of `to`."),
59
+ agentRadius: z
60
+ .number()
61
+ .min(0.1)
62
+ .max(50)
63
+ .optional()
64
+ .describe("How wide the walker is, in studs. Defaults to 2 — a standard " +
65
+ "character. Raise it to ask whether a bigger NPC fits through the " +
66
+ "same gaps a player does."),
67
+ agentHeight: z
68
+ .number()
69
+ .min(0.1)
70
+ .max(100)
71
+ .optional()
72
+ .describe("How tall the walker is. Defaults to 5, a standard character."),
73
+ canClimb: z.boolean().optional().describe("Whether it may climb truss. Off by default."),
74
+ spacing: z
75
+ .number()
76
+ .min(0.1)
77
+ .max(100)
78
+ .optional()
79
+ .describe("Studs between waypoints, default 4. Tighter follows the geometry more " +
80
+ "closely; wider is a coarser route."),
81
+ costs: z
82
+ .record(z.string(), z.number())
83
+ .optional()
84
+ .describe('Material or PathfindingModifier label → cost, e.g. { "Water": 20 } to ' +
85
+ "avoid swimming. Higher is more avoided; the route chosen is the " +
86
+ "cheapest total, not the shortest."),
46
87
  direct: z
47
88
  .boolean()
48
89
  .default(false)
@@ -69,15 +110,64 @@ export function registerCharacterTools(context) {
69
110
  },
70
111
  destructive: false,
71
112
  }, async (args) => {
113
+ /*
114
+ * Agent shape travels with both ops, from one place, so a route `path`
115
+ * reports as walkable is a route `moveTo` walks with the same body.
116
+ */
117
+ const agent = {
118
+ agentRadius: args.agentRadius,
119
+ agentHeight: args.agentHeight,
120
+ canJump: args.canJump,
121
+ canClimb: args.canClimb,
122
+ spacing: args.spacing,
123
+ costs: args.costs,
124
+ };
125
+ if (args.op === "path") {
126
+ const route = await bridge.call("character.path", { from: args.from, fromPath: args.fromPath, to: args.to, toPath: args.toPath, ...agent }, { studioId: args.studioId, timeoutMs: 30_000 });
127
+ if (!route.reachable) {
128
+ return text(`No route: ${route.status}.\n` +
129
+ `${route.from} → ${route.to} is ${route.straightLineDistance} studs apart in a ` +
130
+ `straight line, but nothing walkable connects them for an agent this size.\n\n` +
131
+ route.hint);
132
+ }
133
+ const lines = [
134
+ `Reachable — ${route.pathDistance} studs walked vs ${route.straightLineDistance} ` +
135
+ `straight (detour ${route.detour}x), ${route.waypointCount} waypoints, ${route.jumps} jump(s).`,
136
+ ];
137
+ if (route.detour > 2) {
138
+ lines.push("", `That is a long way round for the distance. Something between the two points ` +
139
+ "is forcing a detour — worth a look if it was meant to be a direct route.");
140
+ }
141
+ if (route.jumps > 0) {
142
+ lines.push("", `${route.jumps} jump(s) on this route. Anything that cannot jump — a vehicle, ` +
143
+ "an NPC with jumping disabled — cannot follow it.");
144
+ }
145
+ lines.push("", textOf(table(["index", "action", "position", "label"], route.waypoints, { more: "walking waypoints between these are omitted" })));
146
+ return text(lines.join("\n"));
147
+ }
72
148
  if (args.op === "moveTo") {
73
- const response = await bridge.call("character.moveTo", { to: args.to, path: args.path, direct: args.direct, canJump: args.canJump, player: args.player },
149
+ const response = await bridge.call("character.moveTo", { to: args.to, path: args.path, direct: args.direct, player: args.player, ...agent },
74
150
  // Walking a long route is genuinely slow, and the handler waits for
75
151
  // each waypoint rather than returning before it arrives.
76
152
  { studioId: args.studioId, timeoutMs: 60_000 });
77
153
  const notes = [];
78
154
  if (response.note)
79
155
  notes.push(response.note);
80
- if (!response.arrived && response.pathStatus === "Enum.PathStatus.Success") {
156
+ /*
157
+ * Only add the vague advice when the handler could not name a cause.
158
+ * With `blockedBy` set it already said which instance is in the way,
159
+ * and following that with "something is in the way" reads as if the
160
+ * tool did not know — which it did.
161
+ */
162
+ /*
163
+ * Only when the handler said nothing itself. It already explains what
164
+ * happened in `note`, and appending "something is physically in the
165
+ * way" after "nothing was in the ray's way" contradicts it in the same
166
+ * breath.
167
+ */
168
+ if (!response.arrived &&
169
+ response.note === undefined &&
170
+ response.pathStatus === "Enum.PathStatus.Success") {
81
171
  notes.push("The path was valid but the character did not reach the end — something " +
82
172
  "is physically in the way, or it fell. Take a `screenshot` to see where it stopped.");
83
173
  }
@@ -1 +1 @@
1
- {"version":3,"file":"character.js","sourceRoot":"","sources":["../../src/tools/character.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"character.js","sourceRoot":"","sources":["../../src/tools/character.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,173 @@
1
+ import { z } from "zod";
2
+ import { json, table, text, textOf } from "../lib/format.js";
3
+ import { defineTool } from "../lib/tool.js";
4
+ /**
5
+ * Data store calls cross the network twice — bridge to Studio, Studio to
6
+ * Roblox — and the second hop is a real HTTP request to a service that
7
+ * throttles. A list that walks several pages is several of those in sequence,
8
+ * so the ceiling is generous on purpose.
9
+ */
10
+ const TIMEOUT_MS = 45_000;
11
+ export function registerDataTools(context) {
12
+ const { bridge } = context;
13
+ defineTool(context, {
14
+ name: "datastore",
15
+ title: "Read and write saved data",
16
+ description: "Reads and writes the game's saved data — DataStore and MemoryStore — " +
17
+ "from the connected Studio.\n\n" +
18
+ "This is the only tool here that looks at anything outside the place " +
19
+ "file. Every other tool answers 'is the instance right'; this one " +
20
+ "answers 'is what the player saved right', which is a different " +
21
+ "question and the one behind most reports of lost progress, reset " +
22
+ "stats, or items that come back after a rejoin.\n\n" +
23
+ "`kind=\"data\"` (the default) is DataStoreService: permanent, per-player, " +
24
+ "and version-tracked. `kind=\"memory\"` is MemoryStoreService: a shared " +
25
+ "scratchpad that expires on its own — queues, locks, live leaderboards.\n\n" +
26
+ "The workflow for a bug report is: `list` with no store to see what " +
27
+ "exists, `list` with one to see its keys, `get` the player's key, and — " +
28
+ "the part worth knowing about — `versions` then `get` with a `version` " +
29
+ "to see what that same key held BEFORE it broke. You cannot diagnose a " +
30
+ "bad save by looking only at the bad save.\n\n" +
31
+ "Writes need `confirm: true` on `kind=\"data\"`, because nothing in this " +
32
+ "server can undo one: there is no recording to cancel and no Ctrl+Z. " +
33
+ "Read the key first.\n\n" +
34
+ "DataStore needs 'Enable Studio Access to API Services' ticked in Game " +
35
+ "Settings → Security, and a published place. If it is off, this tool " +
36
+ "says so in those words rather than reporting the raw 502. MemoryStore " +
37
+ "needs neither.",
38
+ inputSchema: {
39
+ op: z
40
+ .enum(["list", "get", "versions", "set", "remove"])
41
+ .default("list")
42
+ .describe("'list' shows stores (no `store`) or a store's keys (with one). " +
43
+ "'versions' is DataStore only and is how you see a key's history."),
44
+ kind: z
45
+ .enum(["data", "memory"])
46
+ .default("data")
47
+ .describe("'data' = DataStoreService, permanent and versioned. 'memory' = " +
48
+ "MemoryStoreService, shared and expiring. They are separate " +
49
+ "storage — a key in one is not in the other."),
50
+ store: z
51
+ .string()
52
+ .optional()
53
+ .describe("Data store name, or the sorted map's name for memory. Omit on " +
54
+ "`list` to see which stores exist."),
55
+ scope: z
56
+ .string()
57
+ .optional()
58
+ .describe("DataStore scope, if the game uses them. Omit for the default — but " +
59
+ "if a store reads as empty and you expected data, a scope is the " +
60
+ "usual reason."),
61
+ key: z.string().optional().describe("The key. Usually the player's UserId as a string."),
62
+ value: z
63
+ .string()
64
+ .optional()
65
+ .describe('set only: the new value as JSON — {"coins":10}, 42, or a bare ' +
66
+ "string. Read the key first and edit what comes back rather than " +
67
+ "writing a value from scratch: a save is usually a whole table and " +
68
+ "writing part of one deletes the rest."),
69
+ version: z
70
+ .string()
71
+ .optional()
72
+ .describe("get only: read this exact version instead of the current value. From `versions`."),
73
+ at: z
74
+ .number()
75
+ .optional()
76
+ .describe("get only: read the version that was current at this Unix time in " +
77
+ "MILLISECONDS. Use when the player says when it broke but no " +
78
+ "version id is known."),
79
+ ttl: z
80
+ .number()
81
+ .int()
82
+ .min(1)
83
+ .max(3_888_000)
84
+ .optional()
85
+ .describe("memory set only: seconds before the value expires. Defaults to an hour."),
86
+ prefix: z.string().optional().describe("list only: only names starting with this."),
87
+ cursor: z.string().optional().describe("list only: continue from a previous call's cursor."),
88
+ limit: z
89
+ .number()
90
+ .int()
91
+ .min(1)
92
+ .max(200)
93
+ .optional()
94
+ .describe("list/versions only: rows to return. Defaults to 50."),
95
+ confirm: z
96
+ .boolean()
97
+ .optional()
98
+ .describe("Required for set and remove on kind=\"data\". This is real player " +
99
+ "data and nothing here can put it back."),
100
+ studioId: z.string().optional().describe("Target Studio; omit for the active one."),
101
+ },
102
+ // Reads dominate, but the tool can write, so it is not annotated read-only.
103
+ readOnly: false,
104
+ destructive: true,
105
+ }, async (args) => {
106
+ const response = await bridge.call(`data.${args.op}`, {
107
+ kind: args.kind,
108
+ store: args.store,
109
+ scope: args.scope,
110
+ key: args.key,
111
+ value: args.value,
112
+ version: args.version,
113
+ at: args.at,
114
+ ttl: args.ttl,
115
+ prefix: args.prefix,
116
+ cursor: args.cursor,
117
+ limit: args.limit,
118
+ confirm: args.confirm,
119
+ }, { studioId: args.studioId, timeoutMs: TIMEOUT_MS });
120
+ if (args.op === "list" || args.op === "versions") {
121
+ const items = response.items ?? [];
122
+ if (items.length === 0) {
123
+ return text(args.store === undefined
124
+ ? "No data stores in this place yet."
125
+ : `Nothing in ${args.store}. If you expected data, check the \`scope\` — a game ` +
126
+ "that used scopes keeps its keys under them, and the default scope looks empty.");
127
+ }
128
+ /*
129
+ * Column choice is per-op rather than inferred from the rows, because
130
+ * an inferred set drifts: `list` over stores has no `key`, over keys
131
+ * has nothing else, and `versions` has three. Naming them keeps each
132
+ * table readable instead of mostly blank.
133
+ */
134
+ const columns = args.op === "versions"
135
+ ? ["version", "created", "deleted"]
136
+ : args.store === undefined
137
+ ? ["store", "created"]
138
+ : args.kind === "memory"
139
+ ? ["key", "value"]
140
+ : ["key"];
141
+ const notes = [];
142
+ if (response.cursor) {
143
+ notes.push(`more available — pass cursor="${response.cursor}"`);
144
+ }
145
+ if (typeof response.budget === "number") {
146
+ notes.push(`${response.budget} requests left in budget`);
147
+ }
148
+ if (args.op === "versions") {
149
+ notes.push('read one with op="get" and its `version`');
150
+ }
151
+ return text(textOf(table(columns, items, {
152
+ more: notes.length > 0 ? notes.join("; ") : undefined,
153
+ })));
154
+ }
155
+ if (args.op === "get" && response.exists === false) {
156
+ /*
157
+ * The advice differs by backend, and the DataStore version of it is
158
+ * nonsense for memory: MemoryStore has no scopes and no version
159
+ * history, so pointing someone at either sends them looking for
160
+ * something that does not exist.
161
+ */
162
+ return text(`${args.key} is not set in ${args.store}.\n` +
163
+ (args.kind === "memory"
164
+ ? "MemoryStore entries expire on their own, so a key written earlier may " +
165
+ "simply have passed its TTL. There is no history to check."
166
+ : "An empty key and a key that was never written look identical here. If a " +
167
+ 'player should have data, check the `scope`, and try op="versions" — a key ' +
168
+ "that was removed still has history."));
169
+ }
170
+ return json(response);
171
+ });
172
+ }
173
+ //# sourceMappingURL=data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data.js","sourceRoot":"","sources":["../../src/tools/data.ts"],"names":[],"mappings":"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"}