breakpoint-mcp 1.0.0 → 1.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/addon/breakpoint_mcp/README.md +28 -0
- package/addon/breakpoint_mcp/bridge_server.gd +121 -0
- package/addon/breakpoint_mcp/icon.png +0 -0
- package/addon/breakpoint_mcp/operations.gd +4578 -0
- package/addon/breakpoint_mcp/plugin.cfg +7 -0
- package/addon/breakpoint_mcp/plugin.gd +64 -0
- package/addon/breakpoint_mcp/runtime_bridge.gd +440 -0
- package/addon/breakpoint_mcp/variant_json.gd +108 -0
- package/dist/cli/args.js +40 -0
- package/dist/cli/clients.js +74 -0
- package/dist/cli/doctor.js +269 -0
- package/dist/cli/init.js +199 -0
- package/dist/config.js +6 -30
- package/dist/index.js +49 -4
- package/dist/tools/editor/animation.js +162 -0
- package/dist/tools/editor/audio.js +109 -0
- package/dist/tools/editor/common.js +31 -0
- package/dist/tools/editor/core.js +49 -0
- package/dist/tools/editor/filesystem.js +35 -0
- package/dist/tools/editor/introspection.js +73 -0
- package/dist/tools/editor/node.js +171 -0
- package/dist/tools/editor/particles.js +96 -0
- package/dist/tools/editor/physics.js +236 -0
- package/dist/tools/editor/project_input_test.js +187 -0
- package/dist/tools/editor/resource.js +104 -0
- package/dist/tools/editor/scene.js +95 -0
- package/dist/tools/editor/shader.js +59 -0
- package/dist/tools/editor/signal.js +67 -0
- package/dist/tools/editor/spatial.js +185 -0
- package/dist/tools/editor/tiles.js +160 -0
- package/dist/tools/editor/ui.js +175 -0
- package/dist/tools/editor.js +39 -1914
- package/package.json +4 -2
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** GPUParticles authoring (process material, amount, lifetime, texture). */
|
|
3
|
+
export function registerParticleTools(server, call) {
|
|
4
|
+
server.registerTool("particles_create", {
|
|
5
|
+
title: "Create particles",
|
|
6
|
+
description: "Add a GPUParticles2D/3D node under a parent in the edited scene (undoable). Optional initial amount (> 0), lifetime (> 0), emitting. In-scene and undoable — not gated.",
|
|
7
|
+
inputSchema: {
|
|
8
|
+
parent_path: z.string().describe("Parent node path relative to the scene root; \".\" for the root"),
|
|
9
|
+
dim: z.enum(["2d", "3d"]).optional().describe("Dimension: \"2d\" (default, GPUParticles2D) or \"3d\" (GPUParticles3D)"),
|
|
10
|
+
name: z.string().optional().describe("Node name (default \"GPUParticles2D\"/\"GPUParticles3D\")"),
|
|
11
|
+
amount: z.number().optional().describe("Number of particles (> 0, default 8)"),
|
|
12
|
+
lifetime: z.number().optional().describe("Particle lifetime in seconds (> 0, default 1)"),
|
|
13
|
+
emitting: z.boolean().optional().describe("Whether the system is emitting (default true)"),
|
|
14
|
+
},
|
|
15
|
+
}, async ({ parent_path, dim, name, amount, lifetime, emitting }) => {
|
|
16
|
+
const params = { parent_path };
|
|
17
|
+
if (dim !== undefined)
|
|
18
|
+
params.dim = dim;
|
|
19
|
+
if (name !== undefined)
|
|
20
|
+
params.name = name;
|
|
21
|
+
if (amount !== undefined)
|
|
22
|
+
params.amount = amount;
|
|
23
|
+
if (lifetime !== undefined)
|
|
24
|
+
params.lifetime = lifetime;
|
|
25
|
+
if (emitting !== undefined)
|
|
26
|
+
params.emitting = emitting;
|
|
27
|
+
return call("particles.create", params);
|
|
28
|
+
});
|
|
29
|
+
server.registerTool("particles_set_process_material", {
|
|
30
|
+
title: "Set particles process material",
|
|
31
|
+
description: "Create a ParticleProcessMaterial and assign it as process_material on a GPUParticles2D/3D in the edited scene (undoable). Optional knobs: gravity [x, y, z], direction [x, y, z], spread, initial_velocity_min/max, scale_min/max, color [r, g, b, a]. GPU particles need a process material to emit. In-scene and undoable — not gated.",
|
|
32
|
+
inputSchema: {
|
|
33
|
+
path: z.string().describe("GPUParticles2D/3D node path relative to the scene root"),
|
|
34
|
+
gravity: z.array(z.number()).optional().describe("Gravity vector [x, y, z]"),
|
|
35
|
+
direction: z.array(z.number()).optional().describe("Emission direction [x, y, z]"),
|
|
36
|
+
spread: z.number().optional().describe("Emission spread in degrees"),
|
|
37
|
+
initial_velocity_min: z.number().optional().describe("Minimum initial velocity"),
|
|
38
|
+
initial_velocity_max: z.number().optional().describe("Maximum initial velocity"),
|
|
39
|
+
scale_min: z.number().optional().describe("Minimum particle scale"),
|
|
40
|
+
scale_max: z.number().optional().describe("Maximum particle scale"),
|
|
41
|
+
color: z.array(z.number()).optional().describe("Base color [r, g, b] or [r, g, b, a] (0..1)"),
|
|
42
|
+
},
|
|
43
|
+
}, async ({ path, gravity, direction, spread, initial_velocity_min, initial_velocity_max, scale_min, scale_max, color }) => {
|
|
44
|
+
const params = { path };
|
|
45
|
+
if (gravity !== undefined)
|
|
46
|
+
params.gravity = gravity;
|
|
47
|
+
if (direction !== undefined)
|
|
48
|
+
params.direction = direction;
|
|
49
|
+
if (spread !== undefined)
|
|
50
|
+
params.spread = spread;
|
|
51
|
+
if (initial_velocity_min !== undefined)
|
|
52
|
+
params.initial_velocity_min = initial_velocity_min;
|
|
53
|
+
if (initial_velocity_max !== undefined)
|
|
54
|
+
params.initial_velocity_max = initial_velocity_max;
|
|
55
|
+
if (scale_min !== undefined)
|
|
56
|
+
params.scale_min = scale_min;
|
|
57
|
+
if (scale_max !== undefined)
|
|
58
|
+
params.scale_max = scale_max;
|
|
59
|
+
if (color !== undefined)
|
|
60
|
+
params.color = color;
|
|
61
|
+
return call("particles.set_process_material", params);
|
|
62
|
+
});
|
|
63
|
+
server.registerTool("particles_set_amount", {
|
|
64
|
+
title: "Set particles amount",
|
|
65
|
+
description: "Set the number of particles (amount, > 0) on a GPUParticles2D/3D in the edited scene (undoable). In-scene and undoable — not gated.",
|
|
66
|
+
inputSchema: {
|
|
67
|
+
path: z.string().describe("GPUParticles2D/3D node path relative to the scene root"),
|
|
68
|
+
amount: z.number().describe("Number of particles (> 0)"),
|
|
69
|
+
},
|
|
70
|
+
}, async ({ path, amount }) => call("particles.set_amount", { path, amount }));
|
|
71
|
+
server.registerTool("particles_set_lifetime", {
|
|
72
|
+
title: "Set particles lifetime",
|
|
73
|
+
description: "Set the particle lifetime in seconds (> 0) on a GPUParticles2D/3D in the edited scene (undoable). In-scene and undoable — not gated.",
|
|
74
|
+
inputSchema: {
|
|
75
|
+
path: z.string().describe("GPUParticles2D/3D node path relative to the scene root"),
|
|
76
|
+
lifetime: z.number().describe("Lifetime in seconds (> 0)"),
|
|
77
|
+
},
|
|
78
|
+
}, async ({ path, lifetime }) => call("particles.set_lifetime", { path, lifetime }));
|
|
79
|
+
server.registerTool("particles_set_emitting", {
|
|
80
|
+
title: "Set particles emitting",
|
|
81
|
+
description: "Toggle whether a GPUParticles2D/3D is emitting in the edited scene (undoable). In-scene and undoable — not gated.",
|
|
82
|
+
inputSchema: {
|
|
83
|
+
path: z.string().describe("GPUParticles2D/3D node path relative to the scene root"),
|
|
84
|
+
emitting: z.boolean().describe("Whether the system is emitting"),
|
|
85
|
+
},
|
|
86
|
+
}, async ({ path, emitting }) => call("particles.set_emitting", { path, emitting }));
|
|
87
|
+
server.registerTool("particles_set_texture", {
|
|
88
|
+
title: "Set particles texture",
|
|
89
|
+
description: "Load a Texture2D from a res:// path and assign it as texture on a GPUParticles2D in the edited scene (undoable). GPUParticles2D only — GPUParticles3D draws meshes and has no texture (returns unsupported). In-scene and undoable — not gated.",
|
|
90
|
+
inputSchema: {
|
|
91
|
+
path: z.string().describe("GPUParticles2D node path relative to the scene root"),
|
|
92
|
+
texture_path: z.string().describe("res:// path to a Texture2D resource"),
|
|
93
|
+
},
|
|
94
|
+
}, async ({ path, texture_path }) => call("particles.set_texture", { path, texture_path }));
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=particles.js.map
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { gate } from "../../confirm.js";
|
|
3
|
+
/** Physics & collision: bodies, shapes, areas, joints, rigidbody tuning, gravity. */
|
|
4
|
+
export function registerPhysicsTools(server, call) {
|
|
5
|
+
server.registerTool("body_create", {
|
|
6
|
+
title: "Create physics body",
|
|
7
|
+
description: "Add a physics body node under a parent in the edited scene (undoable): a StaticBody, RigidBody, CharacterBody, or Area, in 2D or 3D. In-scene and undoable — not gated. Attach collision shapes with collisionshape_add.",
|
|
8
|
+
inputSchema: {
|
|
9
|
+
parent_path: z.string().describe("Parent node path relative to the scene root; \".\" for the root"),
|
|
10
|
+
type: z.enum(["static", "rigid", "character", "area"]).describe("Body kind: static | rigid | character | area"),
|
|
11
|
+
dim: z.enum(["2d", "3d"]).optional().describe("Dimension: \"2d\" (default) or \"3d\""),
|
|
12
|
+
name: z.string().optional().describe("Node name (default the class name, e.g. \"StaticBody2D\")"),
|
|
13
|
+
},
|
|
14
|
+
}, async ({ parent_path, type, dim, name }) => {
|
|
15
|
+
const params = { parent_path, type };
|
|
16
|
+
if (dim !== undefined)
|
|
17
|
+
params.dim = dim;
|
|
18
|
+
if (name !== undefined)
|
|
19
|
+
params.name = name;
|
|
20
|
+
return call("body.create", params);
|
|
21
|
+
});
|
|
22
|
+
server.registerTool("collisionshape_add", {
|
|
23
|
+
title: "Add collision shape",
|
|
24
|
+
description: "Add a CollisionShape2D/3D node carrying a shape resource under a parent (usually a body) in the edited scene (undoable). shape is rect | circle | capsule | polygon; dim selects 2D (Rectangle/Circle/Capsule/ConvexPolygon 2D) or 3D (Box/Sphere/Capsule/ConvexPolygon 3D). In-scene and undoable — not gated.",
|
|
25
|
+
inputSchema: {
|
|
26
|
+
parent_path: z.string().describe("Parent node path (usually a body) relative to the scene root; \".\" for the root"),
|
|
27
|
+
shape: z.enum(["rect", "circle", "capsule", "polygon"]).describe("Shape kind: rect | circle | capsule | polygon"),
|
|
28
|
+
dim: z.enum(["2d", "3d"]).optional().describe("Dimension: \"2d\" (default) or \"3d\""),
|
|
29
|
+
name: z.string().optional().describe("Node name (default \"CollisionShape2D\"/\"CollisionShape3D\")"),
|
|
30
|
+
size: z.array(z.number()).optional().describe("rect: [w, h] (2D) or [w, h, d] (3D)"),
|
|
31
|
+
radius: z.number().optional().describe("circle/capsule radius"),
|
|
32
|
+
height: z.number().optional().describe("capsule height"),
|
|
33
|
+
points: z.array(z.array(z.number())).optional().describe("polygon: convex-hull points, [[x, y], …] (2D, ≥3) or [[x, y, z], …] (3D, ≥4)"),
|
|
34
|
+
},
|
|
35
|
+
}, async ({ parent_path, shape, dim, name, size, radius, height, points }) => {
|
|
36
|
+
const params = { parent_path, shape };
|
|
37
|
+
if (dim !== undefined)
|
|
38
|
+
params.dim = dim;
|
|
39
|
+
if (name !== undefined)
|
|
40
|
+
params.name = name;
|
|
41
|
+
if (size !== undefined)
|
|
42
|
+
params.size = size;
|
|
43
|
+
if (radius !== undefined)
|
|
44
|
+
params.radius = radius;
|
|
45
|
+
if (height !== undefined)
|
|
46
|
+
params.height = height;
|
|
47
|
+
if (points !== undefined)
|
|
48
|
+
params.points = points;
|
|
49
|
+
return call("collisionshape.add", params);
|
|
50
|
+
});
|
|
51
|
+
server.registerTool("body_set_collision_layer", {
|
|
52
|
+
title: "Set collision layer",
|
|
53
|
+
description: "Set the collision_layer bitmask on a physics body or area (CollisionObject2D/3D) in the edited scene (undoable). layer is the integer bitmask of layers this object occupies.",
|
|
54
|
+
inputSchema: {
|
|
55
|
+
path: z.string().describe("Body/Area node path relative to the scene root"),
|
|
56
|
+
layer: z.number().int().describe("collision_layer bitmask (non-negative integer)"),
|
|
57
|
+
},
|
|
58
|
+
}, async ({ path, layer }) => call("body.set_collision_layer", { path, layer }));
|
|
59
|
+
server.registerTool("body_set_collision_mask", {
|
|
60
|
+
title: "Set collision mask",
|
|
61
|
+
description: "Set the collision_mask bitmask on a physics body or area (CollisionObject2D/3D) in the edited scene (undoable). mask is the integer bitmask of layers this object scans for collisions.",
|
|
62
|
+
inputSchema: {
|
|
63
|
+
path: z.string().describe("Body/Area node path relative to the scene root"),
|
|
64
|
+
mask: z.number().int().describe("collision_mask bitmask (non-negative integer)"),
|
|
65
|
+
},
|
|
66
|
+
}, async ({ path, mask }) => call("body.set_collision_mask", { path, mask }));
|
|
67
|
+
server.registerTool("area_set_monitoring", {
|
|
68
|
+
title: "Set area monitoring",
|
|
69
|
+
description: "Set monitoring and/or monitorable on an Area2D/3D in the edited scene (undoable). monitoring = the area detects overlapping bodies/areas; monitorable = other areas can detect it. In-scene and undoable — not gated.",
|
|
70
|
+
inputSchema: {
|
|
71
|
+
path: z.string().describe("Area2D/3D node path relative to the scene root"),
|
|
72
|
+
monitoring: z.boolean().optional().describe("Whether the area detects overlapping bodies/areas"),
|
|
73
|
+
monitorable: z.boolean().optional().describe("Whether other areas can detect this area"),
|
|
74
|
+
},
|
|
75
|
+
}, async ({ path, monitoring, monitorable }) => {
|
|
76
|
+
const params = { path };
|
|
77
|
+
if (monitoring !== undefined)
|
|
78
|
+
params.monitoring = monitoring;
|
|
79
|
+
if (monitorable !== undefined)
|
|
80
|
+
params.monitorable = monitorable;
|
|
81
|
+
return call("area.set_monitoring", params);
|
|
82
|
+
});
|
|
83
|
+
server.registerTool("area_set_gravity", {
|
|
84
|
+
title: "Set area gravity",
|
|
85
|
+
description: "Set the local gravity override of an Area2D/3D in the edited scene (undoable): space_override mode, gravity magnitude, direction, and whether gravity points toward a center (point). In-scene and undoable — not gated.",
|
|
86
|
+
inputSchema: {
|
|
87
|
+
path: z.string().describe("Area2D/3D node path relative to the scene root"),
|
|
88
|
+
space_override: z.enum(["disabled", "combine", "combine_replace", "replace", "replace_combine"]).optional().describe("How this area's gravity combines with the global/other areas"),
|
|
89
|
+
gravity: z.number().optional().describe("Gravity magnitude (units/s^2)"),
|
|
90
|
+
direction: z.array(z.number()).optional().describe("Gravity direction [x, y] (2D) or [x, y, z] (3D)"),
|
|
91
|
+
point: z.boolean().optional().describe("If true, gravity pulls toward the area's gravity point instead of a direction"),
|
|
92
|
+
},
|
|
93
|
+
}, async ({ path, space_override, gravity, direction, point }) => {
|
|
94
|
+
const params = { path };
|
|
95
|
+
if (space_override !== undefined)
|
|
96
|
+
params.space_override = space_override;
|
|
97
|
+
if (gravity !== undefined)
|
|
98
|
+
params.gravity = gravity;
|
|
99
|
+
if (direction !== undefined)
|
|
100
|
+
params.direction = direction;
|
|
101
|
+
if (point !== undefined)
|
|
102
|
+
params.point = point;
|
|
103
|
+
return call("area.set_gravity", params);
|
|
104
|
+
});
|
|
105
|
+
server.registerTool("joint_create", {
|
|
106
|
+
title: "Create physics joint",
|
|
107
|
+
description: "Add a physics joint node under a parent in the edited scene (undoable). 2D types: pin | groove | spring (PinJoint2D/GrooveJoint2D/DampedSpringJoint2D); 3D types: pin | hinge | slider | cone_twist | generic6dof (PinJoint3D/HingeJoint3D/SliderJoint3D/ConeTwistJoint3D/Generic6DOFJoint3D). Optionally wire node_a/node_b to the two bodies. In-scene and undoable — not gated.",
|
|
108
|
+
inputSchema: {
|
|
109
|
+
parent_path: z.string().describe("Parent node path relative to the scene root; \".\" for the root"),
|
|
110
|
+
type: z.enum(["pin", "groove", "spring", "hinge", "slider", "cone_twist", "generic6dof"]).describe("Joint kind; pin works in both dims, the rest are dim-specific"),
|
|
111
|
+
dim: z.enum(["2d", "3d"]).optional().describe("Dimension: \"2d\" (default) or \"3d\""),
|
|
112
|
+
name: z.string().optional().describe("Node name (default the class name, e.g. \"PinJoint2D\")"),
|
|
113
|
+
node_a: z.string().optional().describe("NodePath (relative to the joint) of the first body"),
|
|
114
|
+
node_b: z.string().optional().describe("NodePath (relative to the joint) of the second body"),
|
|
115
|
+
},
|
|
116
|
+
}, async ({ parent_path, type, dim, name, node_a, node_b }) => {
|
|
117
|
+
const params = { parent_path, type };
|
|
118
|
+
if (dim !== undefined)
|
|
119
|
+
params.dim = dim;
|
|
120
|
+
if (name !== undefined)
|
|
121
|
+
params.name = name;
|
|
122
|
+
if (node_a !== undefined)
|
|
123
|
+
params.node_a = node_a;
|
|
124
|
+
if (node_b !== undefined)
|
|
125
|
+
params.node_b = node_b;
|
|
126
|
+
return call("joint.create", params);
|
|
127
|
+
});
|
|
128
|
+
server.registerTool("joint_set_bodies", {
|
|
129
|
+
title: "Set joint bodies",
|
|
130
|
+
description: "Set node_a and/or node_b on an existing Joint2D/3D in the edited scene (undoable) — the NodePaths of the two bodies the joint connects, relative to the joint node. In-scene and undoable — not gated.",
|
|
131
|
+
inputSchema: {
|
|
132
|
+
path: z.string().describe("Joint2D/3D node path relative to the scene root"),
|
|
133
|
+
node_a: z.string().optional().describe("NodePath (relative to the joint) of the first body"),
|
|
134
|
+
node_b: z.string().optional().describe("NodePath (relative to the joint) of the second body"),
|
|
135
|
+
},
|
|
136
|
+
}, async ({ path, node_a, node_b }) => {
|
|
137
|
+
const params = { path };
|
|
138
|
+
if (node_a !== undefined)
|
|
139
|
+
params.node_a = node_a;
|
|
140
|
+
if (node_b !== undefined)
|
|
141
|
+
params.node_b = node_b;
|
|
142
|
+
return call("joint.set_bodies", params);
|
|
143
|
+
});
|
|
144
|
+
server.registerTool("collisionpolygon_add", {
|
|
145
|
+
title: "Add collision polygon",
|
|
146
|
+
description: "Add a CollisionPolygon2D/3D node carrying a polygon under a parent (usually a body) in the edited scene (undoable). points is a 2D outline [[x, y], …] (≥3); for 3D it is extruded along Z by depth. 2D build_mode is solids | segments. In-scene and undoable — not gated.",
|
|
147
|
+
inputSchema: {
|
|
148
|
+
parent_path: z.string().describe("Parent node path (usually a body) relative to the scene root; \".\" for the root"),
|
|
149
|
+
points: z.array(z.array(z.number())).describe("Polygon outline points [[x, y], …] (≥3); a 2D outline even for 3D"),
|
|
150
|
+
dim: z.enum(["2d", "3d"]).optional().describe("Dimension: \"2d\" (default) or \"3d\""),
|
|
151
|
+
name: z.string().optional().describe("Node name (default \"CollisionPolygon2D\"/\"CollisionPolygon3D\")"),
|
|
152
|
+
build_mode: z.enum(["solids", "segments"]).optional().describe("2D only: solids (default) or segments"),
|
|
153
|
+
depth: z.number().optional().describe("3D only: extrusion depth along Z (default 1.0)"),
|
|
154
|
+
},
|
|
155
|
+
}, async ({ parent_path, points, dim, name, build_mode, depth }) => {
|
|
156
|
+
const params = { parent_path, points };
|
|
157
|
+
if (dim !== undefined)
|
|
158
|
+
params.dim = dim;
|
|
159
|
+
if (name !== undefined)
|
|
160
|
+
params.name = name;
|
|
161
|
+
if (build_mode !== undefined)
|
|
162
|
+
params.build_mode = build_mode;
|
|
163
|
+
if (depth !== undefined)
|
|
164
|
+
params.depth = depth;
|
|
165
|
+
return call("collisionpolygon.add", params);
|
|
166
|
+
});
|
|
167
|
+
server.registerTool("rigidbody_set_properties", {
|
|
168
|
+
title: "Set rigidbody properties",
|
|
169
|
+
description: "Tune a RigidBody2D/3D in the edited scene (undoable): mass (> 0), gravity_scale, linear_damp, angular_damp. Only the provided properties change. In-scene and undoable — not gated.",
|
|
170
|
+
inputSchema: {
|
|
171
|
+
path: z.string().describe("RigidBody2D/3D node path relative to the scene root"),
|
|
172
|
+
mass: z.number().optional().describe("Body mass (> 0)"),
|
|
173
|
+
gravity_scale: z.number().optional().describe("Multiplier on gravity (1 = normal, 0 = float)"),
|
|
174
|
+
linear_damp: z.number().optional().describe("Linear damping (≥ 0)"),
|
|
175
|
+
angular_damp: z.number().optional().describe("Angular damping (≥ 0)"),
|
|
176
|
+
},
|
|
177
|
+
}, async ({ path, mass, gravity_scale, linear_damp, angular_damp }) => {
|
|
178
|
+
const params = { path };
|
|
179
|
+
if (mass !== undefined)
|
|
180
|
+
params.mass = mass;
|
|
181
|
+
if (gravity_scale !== undefined)
|
|
182
|
+
params.gravity_scale = gravity_scale;
|
|
183
|
+
if (linear_damp !== undefined)
|
|
184
|
+
params.linear_damp = linear_damp;
|
|
185
|
+
if (angular_damp !== undefined)
|
|
186
|
+
params.angular_damp = angular_damp;
|
|
187
|
+
return call("rigidbody.set_properties", params);
|
|
188
|
+
});
|
|
189
|
+
server.registerTool("body_set_physics_material", {
|
|
190
|
+
title: "Set body physics material",
|
|
191
|
+
description: "Create a PhysicsMaterial and assign it as physics_material_override on a StaticBody/RigidBody (2D or 3D) in the edited scene (undoable): friction (default 1), bounce (default 0), rough, absorbent. In-scene and undoable — not gated.",
|
|
192
|
+
inputSchema: {
|
|
193
|
+
path: z.string().describe("StaticBody/RigidBody 2D/3D node path relative to the scene root"),
|
|
194
|
+
friction: z.number().optional().describe("Surface friction 0..1 (default 1)"),
|
|
195
|
+
bounce: z.number().optional().describe("Restitution/bounciness 0..1 (default 0)"),
|
|
196
|
+
rough: z.boolean().optional().describe("Rough friction combine mode (default false)"),
|
|
197
|
+
absorbent: z.boolean().optional().describe("Absorbent bounce combine mode (default false)"),
|
|
198
|
+
},
|
|
199
|
+
}, async ({ path, friction, bounce, rough, absorbent }) => {
|
|
200
|
+
const params = { path };
|
|
201
|
+
if (friction !== undefined)
|
|
202
|
+
params.friction = friction;
|
|
203
|
+
if (bounce !== undefined)
|
|
204
|
+
params.bounce = bounce;
|
|
205
|
+
if (rough !== undefined)
|
|
206
|
+
params.rough = rough;
|
|
207
|
+
if (absorbent !== undefined)
|
|
208
|
+
params.absorbent = absorbent;
|
|
209
|
+
return call("body.set_physics_material", params);
|
|
210
|
+
});
|
|
211
|
+
server.registerTool("physics_set_gravity", {
|
|
212
|
+
title: "Set project gravity",
|
|
213
|
+
description: "Write the project's default gravity for 2D or 3D (ProjectSettings physics/{2d,3d}/default_gravity + default_gravity_vector). Set save=true to persist to project.godot. DESTRUCTIVE (project-wide setting) — gated by confirmation.",
|
|
214
|
+
inputSchema: {
|
|
215
|
+
dim: z.enum(["2d", "3d"]).optional().describe("Which gravity to set: \"2d\" (default) or \"3d\""),
|
|
216
|
+
magnitude: z.number().optional().describe("Gravity magnitude (default 2D 980, 3D 9.8)"),
|
|
217
|
+
direction: z.array(z.number()).optional().describe("Gravity direction vector [x, y] (2D) or [x, y, z] (3D)"),
|
|
218
|
+
save: z.boolean().optional().describe("Persist to project.godot (default false)"),
|
|
219
|
+
confirm: z.boolean().optional().describe("Auto-approve this destructive action (skip the confirmation prompt)"),
|
|
220
|
+
},
|
|
221
|
+
}, async ({ dim, magnitude, direction, save, confirm }) => {
|
|
222
|
+
const blocked = await gate(server, confirm, `Set project ${dim ?? "2d"} gravity${save ? " and save project.godot" : ""}`);
|
|
223
|
+
if (blocked)
|
|
224
|
+
return blocked;
|
|
225
|
+
const params = {};
|
|
226
|
+
if (dim !== undefined)
|
|
227
|
+
params.dim = dim;
|
|
228
|
+
if (magnitude !== undefined)
|
|
229
|
+
params.magnitude = magnitude;
|
|
230
|
+
if (direction !== undefined)
|
|
231
|
+
params.direction = direction;
|
|
232
|
+
params.save = save ?? false;
|
|
233
|
+
return call("physics.set_gravity", params);
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=physics.js.map
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { gate } from "../../confirm.js";
|
|
3
|
+
/** InputMap, extended project config (autoloads / export presets / main scene / settings), editor settings, and test-framework detection. */
|
|
4
|
+
export function registerProjectInputTestTools(server, call) {
|
|
5
|
+
server.registerTool("inputmap_add_action", {
|
|
6
|
+
title: "Add input action",
|
|
7
|
+
description: "Define a project input action (ProjectSettings input/<name>) with an empty event list and a deadzone. Set save=true to persist to project.godot. DESTRUCTIVE (project-wide input map) — gated by confirmation.",
|
|
8
|
+
inputSchema: {
|
|
9
|
+
name: z.string().describe("Action name (without the input/ prefix)"),
|
|
10
|
+
deadzone: z.number().optional().describe("Analog deadzone 0..1 (default 0.5)"),
|
|
11
|
+
save: z.boolean().optional().describe("Persist to project.godot (default false)"),
|
|
12
|
+
confirm: z.boolean().optional().describe("Auto-approve this destructive action (skip the confirmation prompt)"),
|
|
13
|
+
},
|
|
14
|
+
}, async ({ name, deadzone, save, confirm }) => {
|
|
15
|
+
const blocked = await gate(server, confirm, `Add input action "${name}"${save ? " and save project.godot" : ""}`);
|
|
16
|
+
if (blocked)
|
|
17
|
+
return blocked;
|
|
18
|
+
const params = { name };
|
|
19
|
+
if (deadzone !== undefined)
|
|
20
|
+
params.deadzone = deadzone;
|
|
21
|
+
if (save !== undefined)
|
|
22
|
+
params.save = save;
|
|
23
|
+
return call("inputmap.add_action", params);
|
|
24
|
+
});
|
|
25
|
+
server.registerTool("inputmap_add_event", {
|
|
26
|
+
title: "Add input event to action",
|
|
27
|
+
description: "Append an input event to an existing project input action. 'event' is { type: key|mouse_button|joy_button|joy_motion, ... } — key: keycode or physical_keycode as a name like \"A\"/\"Space\" or an int; mouse_button/joy_button: button_index; joy_motion: axis + axis_value. Set save=true to persist. DESTRUCTIVE — gated by confirmation.",
|
|
28
|
+
inputSchema: {
|
|
29
|
+
name: z.string().describe("Existing action name (without the input/ prefix)"),
|
|
30
|
+
event: z
|
|
31
|
+
.object({
|
|
32
|
+
type: z.enum(["key", "mouse_button", "joy_button", "joy_motion"]).describe("Event type"),
|
|
33
|
+
keycode: z.union([z.string(), z.number()]).optional().describe("Key name or code (type=key)"),
|
|
34
|
+
physical_keycode: z.union([z.string(), z.number()]).optional().describe("Physical key name or code (type=key)"),
|
|
35
|
+
button_index: z.number().optional().describe("Button index (mouse_button/joy_button)"),
|
|
36
|
+
axis: z.number().optional().describe("Joypad axis (joy_motion)"),
|
|
37
|
+
axis_value: z.number().optional().describe("Joypad axis value (joy_motion)"),
|
|
38
|
+
})
|
|
39
|
+
.describe("Input event descriptor"),
|
|
40
|
+
save: z.boolean().optional().describe("Persist to project.godot (default false)"),
|
|
41
|
+
confirm: z.boolean().optional().describe("Auto-approve this destructive action (skip the confirmation prompt)"),
|
|
42
|
+
},
|
|
43
|
+
}, async ({ name, event, save, confirm }) => {
|
|
44
|
+
const blocked = await gate(server, confirm, `Add input event to "${name}"`);
|
|
45
|
+
if (blocked)
|
|
46
|
+
return blocked;
|
|
47
|
+
const params = { name, event };
|
|
48
|
+
if (save !== undefined)
|
|
49
|
+
params.save = save;
|
|
50
|
+
return call("inputmap.add_event", params);
|
|
51
|
+
});
|
|
52
|
+
server.registerTool("inputmap_list", {
|
|
53
|
+
title: "List input actions",
|
|
54
|
+
description: "List all project-defined input actions (ProjectSettings input/*) with their deadzone and events (class + human-readable text). Read-only.",
|
|
55
|
+
inputSchema: {},
|
|
56
|
+
}, async () => call("inputmap.list"));
|
|
57
|
+
server.registerTool("inputmap_erase_action", {
|
|
58
|
+
title: "Erase input action",
|
|
59
|
+
description: "Remove a project input action (ProjectSettings input/<name>). Set save=true to persist to project.godot. DESTRUCTIVE — gated by confirmation.",
|
|
60
|
+
inputSchema: {
|
|
61
|
+
name: z.string().describe("Action name (without the input/ prefix)"),
|
|
62
|
+
save: z.boolean().optional().describe("Persist to project.godot (default false)"),
|
|
63
|
+
confirm: z.boolean().optional().describe("Auto-approve this destructive action (skip the confirmation prompt)"),
|
|
64
|
+
},
|
|
65
|
+
}, async ({ name, save, confirm }) => {
|
|
66
|
+
const blocked = await gate(server, confirm, `Erase input action "${name}"${save ? " and save project.godot" : ""}`);
|
|
67
|
+
if (blocked)
|
|
68
|
+
return blocked;
|
|
69
|
+
const params = { name };
|
|
70
|
+
if (save !== undefined)
|
|
71
|
+
params.save = save;
|
|
72
|
+
return call("inputmap.erase_action", params);
|
|
73
|
+
});
|
|
74
|
+
server.registerTool("project_add_autoload", {
|
|
75
|
+
title: "Add autoload singleton",
|
|
76
|
+
description: "Register an autoload (ProjectSettings autoload/<name>) pointing at a res:// script or scene, enabled as a global singleton by default. Set save=true to persist to project.godot. DESTRUCTIVE — gated by confirmation.",
|
|
77
|
+
inputSchema: {
|
|
78
|
+
name: z.string().describe("Autoload / singleton name"),
|
|
79
|
+
path: z.string().describe("res:// path to a .gd script or .tscn scene"),
|
|
80
|
+
enabled: z.boolean().optional().describe("Enable as a global singleton (default true)"),
|
|
81
|
+
save: z.boolean().optional().describe("Persist to project.godot (default false)"),
|
|
82
|
+
confirm: z.boolean().optional().describe("Auto-approve this destructive action (skip the confirmation prompt)"),
|
|
83
|
+
},
|
|
84
|
+
}, async ({ name, path, enabled, save, confirm }) => {
|
|
85
|
+
const blocked = await gate(server, confirm, `Add autoload "${name}" -> ${path}${save ? " and save project.godot" : ""}`);
|
|
86
|
+
if (blocked)
|
|
87
|
+
return blocked;
|
|
88
|
+
const params = { name, path };
|
|
89
|
+
if (enabled !== undefined)
|
|
90
|
+
params.enabled = enabled;
|
|
91
|
+
if (save !== undefined)
|
|
92
|
+
params.save = save;
|
|
93
|
+
return call("project.add_autoload", params);
|
|
94
|
+
});
|
|
95
|
+
server.registerTool("project_remove_autoload", {
|
|
96
|
+
title: "Remove autoload singleton",
|
|
97
|
+
description: "Remove an autoload (ProjectSettings autoload/<name>). Set save=true to persist to project.godot. DESTRUCTIVE — gated by confirmation.",
|
|
98
|
+
inputSchema: {
|
|
99
|
+
name: z.string().describe("Autoload / singleton name"),
|
|
100
|
+
save: z.boolean().optional().describe("Persist to project.godot (default false)"),
|
|
101
|
+
confirm: z.boolean().optional().describe("Auto-approve this destructive action (skip the confirmation prompt)"),
|
|
102
|
+
},
|
|
103
|
+
}, async ({ name, save, confirm }) => {
|
|
104
|
+
const blocked = await gate(server, confirm, `Remove autoload "${name}"${save ? " and save project.godot" : ""}`);
|
|
105
|
+
if (blocked)
|
|
106
|
+
return blocked;
|
|
107
|
+
const params = { name };
|
|
108
|
+
if (save !== undefined)
|
|
109
|
+
params.save = save;
|
|
110
|
+
return call("project.remove_autoload", params);
|
|
111
|
+
});
|
|
112
|
+
server.registerTool("project_add_export_preset", {
|
|
113
|
+
title: "Add export preset",
|
|
114
|
+
description: "Append an export preset to res://export_presets.cfg for a platform (e.g. \"Windows Desktop\", \"Web\", \"Linux/X11\", \"macOS\"). Returns the preset's index. DESTRUCTIVE (writes export_presets.cfg) — gated by confirmation.",
|
|
115
|
+
inputSchema: {
|
|
116
|
+
name: z.string().describe("Preset display name"),
|
|
117
|
+
platform: z.string().describe("Export platform name as shown in the editor"),
|
|
118
|
+
runnable: z.boolean().optional().describe("Mark the preset runnable (default true)"),
|
|
119
|
+
export_path: z.string().optional().describe("Default export output path"),
|
|
120
|
+
confirm: z.boolean().optional().describe("Auto-approve this destructive action (skip the confirmation prompt)"),
|
|
121
|
+
},
|
|
122
|
+
}, async ({ name, platform, runnable, export_path, confirm }) => {
|
|
123
|
+
const blocked = await gate(server, confirm, `Add export preset "${name}" (${platform})`);
|
|
124
|
+
if (blocked)
|
|
125
|
+
return blocked;
|
|
126
|
+
const params = { name, platform };
|
|
127
|
+
if (runnable !== undefined)
|
|
128
|
+
params.runnable = runnable;
|
|
129
|
+
if (export_path !== undefined)
|
|
130
|
+
params.export_path = export_path;
|
|
131
|
+
return call("project.add_export_preset", params);
|
|
132
|
+
});
|
|
133
|
+
server.registerTool("project_set_main_scene", {
|
|
134
|
+
title: "Set main scene",
|
|
135
|
+
description: "Set the project's main scene (ProjectSettings application/run/main_scene) to an existing res:// .tscn/.scn. Set save=true to persist to project.godot. DESTRUCTIVE — gated by confirmation.",
|
|
136
|
+
inputSchema: {
|
|
137
|
+
path: z.string().describe("res:// path to the scene to run first"),
|
|
138
|
+
save: z.boolean().optional().describe("Persist to project.godot (default false)"),
|
|
139
|
+
confirm: z.boolean().optional().describe("Auto-approve this destructive action (skip the confirmation prompt)"),
|
|
140
|
+
},
|
|
141
|
+
}, async ({ path, save, confirm }) => {
|
|
142
|
+
const blocked = await gate(server, confirm, `Set main scene to ${path}${save ? " and save project.godot" : ""}`);
|
|
143
|
+
if (blocked)
|
|
144
|
+
return blocked;
|
|
145
|
+
const params = { path };
|
|
146
|
+
if (save !== undefined)
|
|
147
|
+
params.save = save;
|
|
148
|
+
return call("project.set_main_scene", params);
|
|
149
|
+
});
|
|
150
|
+
server.registerTool("project_list_settings", {
|
|
151
|
+
title: "List project settings",
|
|
152
|
+
description: "List ProjectSettings keys and values, optionally filtered by a dotted-key prefix (e.g. \"input/\", \"autoload/\", \"application/\"). Read-only.",
|
|
153
|
+
inputSchema: {
|
|
154
|
+
prefix: z.string().optional().describe("Only return keys starting with this prefix (default: all)"),
|
|
155
|
+
},
|
|
156
|
+
}, async ({ prefix }) => call("project.list_settings", prefix !== undefined ? { prefix } : {}));
|
|
157
|
+
server.registerTool("editorsettings_get_set", {
|
|
158
|
+
title: "Get or set an editor setting",
|
|
159
|
+
description: "Read an EditorSettings value by name; if 'value' is provided, write it instead (persists to the editor's global config). Reading is read-only; writing is DESTRUCTIVE (mutates the editor config) — gated by confirmation.",
|
|
160
|
+
inputSchema: {
|
|
161
|
+
name: z.string().describe("EditorSettings key, e.g. interface/editor/code_font_size"),
|
|
162
|
+
value: z.any().optional().describe("If provided, set this value (rich types use the {\"__type__\":...} tagging convention)"),
|
|
163
|
+
confirm: z.boolean().optional().describe("Auto-approve the write (skip the confirmation prompt)"),
|
|
164
|
+
},
|
|
165
|
+
}, async ({ name, value, confirm }) => {
|
|
166
|
+
if (value !== undefined) {
|
|
167
|
+
const blocked = await gate(server, confirm, `Set editor setting "${name}"`);
|
|
168
|
+
if (blocked)
|
|
169
|
+
return blocked;
|
|
170
|
+
return call("editorsettings.get_set", { name, value });
|
|
171
|
+
}
|
|
172
|
+
return call("editorsettings.get_set", { name });
|
|
173
|
+
});
|
|
174
|
+
server.registerTool("test_detect", {
|
|
175
|
+
title: "Detect test framework",
|
|
176
|
+
description: "Detect an installed GDScript test framework (GUT or GdUnit4) in the project. Returns { framework: gut|gdunit4|none, path, version }. Read-only.",
|
|
177
|
+
inputSchema: {},
|
|
178
|
+
}, async () => call("test.detect"));
|
|
179
|
+
server.registerTool("test_list", {
|
|
180
|
+
title: "List test scripts",
|
|
181
|
+
description: "List GDScript test scripts (files named test_*.gd or *_test.gd) under a directory (default res://test), searched recursively. Read-only.",
|
|
182
|
+
inputSchema: {
|
|
183
|
+
dir: z.string().optional().describe("Directory to search (default res://test)"),
|
|
184
|
+
},
|
|
185
|
+
}, async ({ dir }) => call("test.list", dir !== undefined ? { dir } : {}));
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=project_input_test.js.map
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { gate } from "../../confirm.js";
|
|
3
|
+
/** Resource (.tres/.res) create / load / save / property / import ops. */
|
|
4
|
+
export function registerResourceTools(server, call) {
|
|
5
|
+
server.registerTool("resource_create", {
|
|
6
|
+
title: "Create resource",
|
|
7
|
+
description: "Instantiate a Resource subclass and save it as a new file. DESTRUCTIVE (writes a file) — gated by confirmation. Optional initial properties use the tagged-Variant convention.",
|
|
8
|
+
inputSchema: {
|
|
9
|
+
class_name: z.string().describe("Resource subclass to instantiate, e.g. StyleBoxFlat, Theme, GDScript"),
|
|
10
|
+
to_path: z.string().describe("Destination res:// path, e.g. res://styles/panel.tres"),
|
|
11
|
+
properties: z.record(z.any()).optional().describe("Initial property values (JSON scalars or __type__-tagged Variants)"),
|
|
12
|
+
confirm: z.boolean().optional().describe("Auto-approve this destructive action (skip the confirmation prompt)"),
|
|
13
|
+
},
|
|
14
|
+
}, async ({ class_name, to_path, properties, confirm }) => {
|
|
15
|
+
const blocked = await gate(server, confirm, `Create ${class_name} resource at ${to_path}`);
|
|
16
|
+
if (blocked)
|
|
17
|
+
return blocked;
|
|
18
|
+
return call("resource.create", properties !== undefined ? { class_name, to_path, properties } : { class_name, to_path });
|
|
19
|
+
});
|
|
20
|
+
server.registerTool("resource_load", {
|
|
21
|
+
title: "Load resource",
|
|
22
|
+
description: "Load a resource file and return its class, resource_name, and inspector-visible property list. Read-only.",
|
|
23
|
+
inputSchema: { path: z.string().describe("Resource res:// path") },
|
|
24
|
+
}, async ({ path }) => call("resource.load", { path }));
|
|
25
|
+
server.registerTool("resource_save", {
|
|
26
|
+
title: "Save resource",
|
|
27
|
+
description: "Load a resource and (re-)save it, optionally to a new path and with ResourceSaver flags. DESTRUCTIVE (writes a file) — gated by confirmation. Shares subresources by reference; use resource_duplicate for an independent copy.",
|
|
28
|
+
inputSchema: {
|
|
29
|
+
from_path: z.string().describe("Source resource res:// path"),
|
|
30
|
+
to_path: z.string().optional().describe("Destination res:// path (default: overwrite from_path)"),
|
|
31
|
+
flags: z.number().int().optional().describe("ResourceSaver.SaverFlags bitmask (e.g. 32 = FLAG_COMPRESS)"),
|
|
32
|
+
confirm: z.boolean().optional().describe("Auto-approve this destructive action (skip the confirmation prompt)"),
|
|
33
|
+
},
|
|
34
|
+
}, async ({ from_path, to_path, flags, confirm }) => {
|
|
35
|
+
const blocked = await gate(server, confirm, `Save resource ${from_path}${to_path ? ` to ${to_path}` : ""}`);
|
|
36
|
+
if (blocked)
|
|
37
|
+
return blocked;
|
|
38
|
+
const params = { from_path };
|
|
39
|
+
if (to_path !== undefined)
|
|
40
|
+
params.to_path = to_path;
|
|
41
|
+
if (flags !== undefined)
|
|
42
|
+
params.flags = flags;
|
|
43
|
+
return call("resource.save", params);
|
|
44
|
+
});
|
|
45
|
+
server.registerTool("resource_duplicate", {
|
|
46
|
+
title: "Duplicate resource",
|
|
47
|
+
description: "Load a resource, duplicate it (optionally deep, cloning subresources), and save the copy to a new path. DESTRUCTIVE (writes a file) — gated by confirmation.",
|
|
48
|
+
inputSchema: {
|
|
49
|
+
path: z.string().describe("Source resource res:// path"),
|
|
50
|
+
to_path: z.string().describe("Destination res:// path for the copy"),
|
|
51
|
+
deep: z.boolean().optional().describe("Deep-duplicate subresources (default false)"),
|
|
52
|
+
confirm: z.boolean().optional().describe("Auto-approve this destructive action (skip the confirmation prompt)"),
|
|
53
|
+
},
|
|
54
|
+
}, async ({ path, to_path, deep, confirm }) => {
|
|
55
|
+
const blocked = await gate(server, confirm, `Duplicate resource ${path} to ${to_path}`);
|
|
56
|
+
if (blocked)
|
|
57
|
+
return blocked;
|
|
58
|
+
return call("resource.duplicate", deep !== undefined ? { path, to_path, deep } : { path, to_path });
|
|
59
|
+
});
|
|
60
|
+
server.registerTool("resource_get_property", {
|
|
61
|
+
title: "Get resource property",
|
|
62
|
+
description: "Read a single property of a resource file by name. Read-only. The value comes back tagged (Variant convention).",
|
|
63
|
+
inputSchema: {
|
|
64
|
+
path: z.string().describe("Resource res:// path"),
|
|
65
|
+
property: z.string().describe("Property name"),
|
|
66
|
+
},
|
|
67
|
+
}, async ({ path, property }) => call("resource.get_property", { path, property }));
|
|
68
|
+
server.registerTool("resource_set_property", {
|
|
69
|
+
title: "Set resource property",
|
|
70
|
+
description: "Set a single property on a resource file and save it. DESTRUCTIVE (writes a file) — gated by confirmation. The value uses the tagged-Variant convention.",
|
|
71
|
+
inputSchema: {
|
|
72
|
+
path: z.string().describe("Resource res:// path"),
|
|
73
|
+
property: z.string().describe("Property name"),
|
|
74
|
+
value: z.any().describe("New value (JSON scalar or __type__-tagged Variant)"),
|
|
75
|
+
confirm: z.boolean().optional().describe("Auto-approve this destructive action (skip the confirmation prompt)"),
|
|
76
|
+
},
|
|
77
|
+
}, async ({ path, property, value, confirm }) => {
|
|
78
|
+
const blocked = await gate(server, confirm, `Set ${property} on ${path}`);
|
|
79
|
+
if (blocked)
|
|
80
|
+
return blocked;
|
|
81
|
+
return call("resource.set_property", { path, property, value });
|
|
82
|
+
});
|
|
83
|
+
server.registerTool("resource_get_import_settings", {
|
|
84
|
+
title: "Get import settings",
|
|
85
|
+
description: "Read an asset's import metadata (.import): the importer and its parameters. Read-only. Returns imported=false when the asset has no .import sidecar.",
|
|
86
|
+
inputSchema: { path: z.string().describe("Asset res:// path (e.g. res://icon.png)") },
|
|
87
|
+
}, async ({ path }) => call("resource.get_import_settings", { path }));
|
|
88
|
+
server.registerTool("resource_set_import_settings", {
|
|
89
|
+
title: "Set import settings",
|
|
90
|
+
description: "Update import parameters in an asset's .import metadata and trigger a reimport. DESTRUCTIVE (rewrites metadata + reimports) — gated by confirmation. Errors if the asset has no .import sidecar.",
|
|
91
|
+
inputSchema: {
|
|
92
|
+
path: z.string().describe("Asset res:// path"),
|
|
93
|
+
settings: z.record(z.any()).describe("Import params to set (name -> JSON scalar or __type__-tagged Variant)"),
|
|
94
|
+
reimport: z.boolean().optional().describe("Reimport after writing (default true)"),
|
|
95
|
+
confirm: z.boolean().optional().describe("Auto-approve this destructive action (skip the confirmation prompt)"),
|
|
96
|
+
},
|
|
97
|
+
}, async ({ path, settings, reimport, confirm }) => {
|
|
98
|
+
const blocked = await gate(server, confirm, `Set import settings on ${path} and reimport`);
|
|
99
|
+
if (blocked)
|
|
100
|
+
return blocked;
|
|
101
|
+
return call("resource.set_import_settings", reimport !== undefined ? { path, settings, reimport } : { path, settings });
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=resource.js.map
|