@particle-academy/agent-integrations 0.21.2 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bridges/files.d.cts +64 -0
- package/dist/bridges/files.d.ts +64 -0
- package/dist/bridges/map.d.cts +62 -0
- package/dist/bridges/map.d.ts +62 -0
- package/dist/bridges-files.cjs +337 -0
- package/dist/bridges-files.cjs.map +1 -0
- package/dist/bridges-files.js +7 -0
- package/dist/bridges-files.js.map +1 -0
- package/dist/bridges-map.cjs +454 -0
- package/dist/bridges-map.cjs.map +1 -0
- package/dist/bridges-map.js +7 -0
- package/dist/bridges-map.js.map +1 -0
- package/dist/chunk-3VRQGDKV.js +334 -0
- package/dist/chunk-3VRQGDKV.js.map +1 -0
- package/dist/chunk-UOMSY7MZ.js +217 -0
- package/dist/chunk-UOMSY7MZ.js.map +1 -0
- package/dist/index.cjs +596 -57
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/package.json +21 -1
package/dist/index.cjs
CHANGED
|
@@ -1105,7 +1105,7 @@ function registerSceneBridge(host, options) {
|
|
|
1105
1105
|
)
|
|
1106
1106
|
);
|
|
1107
1107
|
};
|
|
1108
|
-
const
|
|
1108
|
+
const newId2 = (kind) => `${kind}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 6)}`;
|
|
1109
1109
|
reg(
|
|
1110
1110
|
"scene_describe",
|
|
1111
1111
|
"Describe the scene \u2014 object count, kinds, camera position.",
|
|
@@ -1149,7 +1149,7 @@ function registerSceneBridge(host, options) {
|
|
|
1149
1149
|
["kind"],
|
|
1150
1150
|
(args) => {
|
|
1151
1151
|
const obj = {
|
|
1152
|
-
id:
|
|
1152
|
+
id: newId2(String(args.kind)),
|
|
1153
1153
|
kind: String(args.kind),
|
|
1154
1154
|
position: parseTriple(args.position),
|
|
1155
1155
|
rotation: parseTriple(args.rotation),
|
|
@@ -1955,11 +1955,548 @@ function serialize(entry) {
|
|
|
1955
1955
|
};
|
|
1956
1956
|
}
|
|
1957
1957
|
|
|
1958
|
+
// src/bridges/map.ts
|
|
1959
|
+
var DEFAULT_AGENT8 = { id: "agent", name: "Agent", color: "#7c3aed" };
|
|
1960
|
+
var num2 = (v, fallback) => typeof v === "number" && Number.isFinite(v) ? v : 0;
|
|
1961
|
+
var str2 = (v, fallback = "") => typeof v === "string" ? v : fallback;
|
|
1962
|
+
var newId = (prefix) => `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 7)}`;
|
|
1963
|
+
function registerMapBridge(host, options) {
|
|
1964
|
+
const { adapter } = options;
|
|
1965
|
+
const agent = { ...DEFAULT_AGENT8, ...options.agent ?? {} };
|
|
1966
|
+
const disposers = [];
|
|
1967
|
+
ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
|
|
1968
|
+
const mTarget = (args, result) => ({
|
|
1969
|
+
kind: "map",
|
|
1970
|
+
elementId: result?.structuredContent?.id ?? args?.id
|
|
1971
|
+
});
|
|
1972
|
+
const reg = (name, description, properties, required, handler, resolveTarget) => {
|
|
1973
|
+
const wrapped = async (args) => {
|
|
1974
|
+
try {
|
|
1975
|
+
return await handler(args);
|
|
1976
|
+
} catch (e) {
|
|
1977
|
+
return errorResult(e instanceof Error ? e.message : String(e));
|
|
1978
|
+
}
|
|
1979
|
+
};
|
|
1980
|
+
const final = resolveTarget ? wrapToolWithActivity(wrapped, {
|
|
1981
|
+
toolName: name,
|
|
1982
|
+
agent: { id: agent.id, name: agent.name, color: agent.color },
|
|
1983
|
+
kind: "map",
|
|
1984
|
+
resolveTarget: ({ args, result }) => resolveTarget(args, result)
|
|
1985
|
+
}) : wrapped;
|
|
1986
|
+
disposers.push(
|
|
1987
|
+
host.registerTool(
|
|
1988
|
+
{
|
|
1989
|
+
name,
|
|
1990
|
+
description,
|
|
1991
|
+
inputSchema: {
|
|
1992
|
+
type: "object",
|
|
1993
|
+
properties,
|
|
1994
|
+
required,
|
|
1995
|
+
additionalProperties: false
|
|
1996
|
+
}
|
|
1997
|
+
},
|
|
1998
|
+
final
|
|
1999
|
+
)
|
|
2000
|
+
);
|
|
2001
|
+
};
|
|
2002
|
+
reg("map_get_state", "Get the map's camera, markers, and current selection.", {}, [], () => {
|
|
2003
|
+
const state = {
|
|
2004
|
+
view: adapter.getView(),
|
|
2005
|
+
markers: adapter.getMarkers(),
|
|
2006
|
+
selectedId: adapter.getSelected()
|
|
2007
|
+
};
|
|
2008
|
+
return textResult(JSON.stringify(state, null, 2), state);
|
|
2009
|
+
});
|
|
2010
|
+
reg(
|
|
2011
|
+
"map_set_view",
|
|
2012
|
+
"Move the camera to an absolute position. Any omitted field is left unchanged.",
|
|
2013
|
+
{
|
|
2014
|
+
lat: { type: "number", description: "New center latitude." },
|
|
2015
|
+
lng: { type: "number", description: "New center longitude." },
|
|
2016
|
+
zoom: { type: "number", description: "New zoom level (higher = closer)." }
|
|
2017
|
+
},
|
|
2018
|
+
[],
|
|
2019
|
+
(args) => {
|
|
2020
|
+
const prev = adapter.getView();
|
|
2021
|
+
const next = {
|
|
2022
|
+
center: {
|
|
2023
|
+
lat: args.lat !== void 0 ? num2(args.lat) : prev.center.lat,
|
|
2024
|
+
lng: args.lng !== void 0 ? num2(args.lng) : prev.center.lng
|
|
2025
|
+
},
|
|
2026
|
+
zoom: args.zoom !== void 0 ? num2(args.zoom) : prev.zoom
|
|
2027
|
+
};
|
|
2028
|
+
adapter.setView(next);
|
|
2029
|
+
fancyAutoCommon.pushUndoEntry(agent.id, {
|
|
2030
|
+
timestamp: Date.now(),
|
|
2031
|
+
bridgeId: "map",
|
|
2032
|
+
action: "map_set_view",
|
|
2033
|
+
label: `Moved camera to ${next.center.lat.toFixed(4)},${next.center.lng.toFixed(4)} z${next.zoom}`,
|
|
2034
|
+
undo: () => adapter.setView(prev),
|
|
2035
|
+
redo: () => adapter.setView(next)
|
|
2036
|
+
});
|
|
2037
|
+
return textResult(`Camera \u2192 ${next.center.lat.toFixed(4)},${next.center.lng.toFixed(4)} z${next.zoom}`, next);
|
|
2038
|
+
},
|
|
2039
|
+
mTarget
|
|
2040
|
+
);
|
|
2041
|
+
reg(
|
|
2042
|
+
"map_pan",
|
|
2043
|
+
"Pan the camera by a relative offset in degrees (positive dLat = north, positive dLng = east).",
|
|
2044
|
+
{ dLat: { type: "number" }, dLng: { type: "number" } },
|
|
2045
|
+
[],
|
|
2046
|
+
(args) => {
|
|
2047
|
+
const prev = adapter.getView();
|
|
2048
|
+
const next = {
|
|
2049
|
+
...prev,
|
|
2050
|
+
center: { lat: prev.center.lat + num2(args.dLat), lng: prev.center.lng + num2(args.dLng) }
|
|
2051
|
+
};
|
|
2052
|
+
adapter.setView(next);
|
|
2053
|
+
fancyAutoCommon.pushUndoEntry(agent.id, {
|
|
2054
|
+
timestamp: Date.now(),
|
|
2055
|
+
bridgeId: "map",
|
|
2056
|
+
action: "map_pan",
|
|
2057
|
+
label: "Panned camera",
|
|
2058
|
+
undo: () => adapter.setView(prev),
|
|
2059
|
+
redo: () => adapter.setView(next)
|
|
2060
|
+
});
|
|
2061
|
+
return textResult(`Panned to ${next.center.lat.toFixed(4)},${next.center.lng.toFixed(4)}`, next);
|
|
2062
|
+
},
|
|
2063
|
+
mTarget
|
|
2064
|
+
);
|
|
2065
|
+
reg(
|
|
2066
|
+
"map_zoom",
|
|
2067
|
+
"Zoom the camera by a relative delta (e.g. +1 zooms in one level, -2 out two).",
|
|
2068
|
+
{ delta: { type: "number" } },
|
|
2069
|
+
["delta"],
|
|
2070
|
+
(args) => {
|
|
2071
|
+
const prev = adapter.getView();
|
|
2072
|
+
const next = { ...prev, zoom: prev.zoom + num2(args.delta) };
|
|
2073
|
+
adapter.setView(next);
|
|
2074
|
+
fancyAutoCommon.pushUndoEntry(agent.id, {
|
|
2075
|
+
timestamp: Date.now(),
|
|
2076
|
+
bridgeId: "map",
|
|
2077
|
+
action: "map_zoom",
|
|
2078
|
+
label: `Zoom \u2192 ${next.zoom}`,
|
|
2079
|
+
undo: () => adapter.setView(prev),
|
|
2080
|
+
redo: () => adapter.setView(next)
|
|
2081
|
+
});
|
|
2082
|
+
return textResult(`Zoom \u2192 ${next.zoom}`, next);
|
|
2083
|
+
}
|
|
2084
|
+
);
|
|
2085
|
+
reg(
|
|
2086
|
+
"map_fit_bounds",
|
|
2087
|
+
"Fit the camera to enclose points. Pass `points`, or omit to fit all current markers.",
|
|
2088
|
+
{
|
|
2089
|
+
points: {
|
|
2090
|
+
type: "array",
|
|
2091
|
+
description: "Points to enclose, e.g. [{lat,lng},\u2026].",
|
|
2092
|
+
items: {
|
|
2093
|
+
type: "object",
|
|
2094
|
+
properties: { lat: { type: "number" }, lng: { type: "number" } },
|
|
2095
|
+
required: ["lat", "lng"]
|
|
2096
|
+
}
|
|
2097
|
+
},
|
|
2098
|
+
padding: { type: "number", description: "Padding in pixels (default 40)." }
|
|
2099
|
+
},
|
|
2100
|
+
[],
|
|
2101
|
+
(args) => {
|
|
2102
|
+
if (!adapter.fitBounds) {
|
|
2103
|
+
return errorResult("Host did not wire fitBounds (pass the <Map onReady> handle's fitBounds).");
|
|
2104
|
+
}
|
|
2105
|
+
const points = Array.isArray(args.points) ? args.points.map((p) => ({ lat: num2(p?.lat), lng: num2(p?.lng) })) : adapter.getMarkers().map((m) => m.position);
|
|
2106
|
+
if (!points.length) {
|
|
2107
|
+
return errorResult("No points to fit (map has no markers).");
|
|
2108
|
+
}
|
|
2109
|
+
adapter.fitBounds(points, args.padding !== void 0 ? num2(args.padding) : void 0);
|
|
2110
|
+
return textResult(`Fit camera to ${points.length} point(s).`);
|
|
2111
|
+
}
|
|
2112
|
+
);
|
|
2113
|
+
reg(
|
|
2114
|
+
"map_add_marker",
|
|
2115
|
+
"Drop a marker. `id` is optional (auto-generated); `icon` is an emoji or 1\u20132 chars.",
|
|
2116
|
+
{
|
|
2117
|
+
id: { type: "string" },
|
|
2118
|
+
lat: { type: "number" },
|
|
2119
|
+
lng: { type: "number" },
|
|
2120
|
+
label: { type: "string" },
|
|
2121
|
+
color: { type: "string", description: "CSS color, e.g. #2563eb." },
|
|
2122
|
+
icon: { type: "string", description: "Emoji / short text in the pin." },
|
|
2123
|
+
draggable: { type: "boolean" },
|
|
2124
|
+
data: { type: "object", description: "Arbitrary JSON payload carried with the marker." }
|
|
2125
|
+
},
|
|
2126
|
+
["lat", "lng"],
|
|
2127
|
+
(args) => {
|
|
2128
|
+
const id = args.id ? str2(args.id) : newId("m");
|
|
2129
|
+
if (adapter.getMarkers().some((m) => m.id === id)) {
|
|
2130
|
+
return errorResult(`A marker with id ${id} already exists \u2014 use map_update_marker.`);
|
|
2131
|
+
}
|
|
2132
|
+
const marker = {
|
|
2133
|
+
id,
|
|
2134
|
+
position: { lat: num2(args.lat), lng: num2(args.lng) },
|
|
2135
|
+
...args.label !== void 0 ? { label: str2(args.label) } : {},
|
|
2136
|
+
...args.color !== void 0 ? { color: str2(args.color) } : {},
|
|
2137
|
+
...args.icon !== void 0 ? { icon: str2(args.icon) } : {},
|
|
2138
|
+
...args.draggable !== void 0 ? { draggable: !!args.draggable } : {},
|
|
2139
|
+
...args.data && typeof args.data === "object" ? { data: args.data } : {}
|
|
2140
|
+
};
|
|
2141
|
+
adapter.setMarkers((all) => [...all, marker]);
|
|
2142
|
+
fancyAutoCommon.pushUndoEntry(agent.id, {
|
|
2143
|
+
timestamp: Date.now(),
|
|
2144
|
+
bridgeId: "map",
|
|
2145
|
+
action: "map_add_marker",
|
|
2146
|
+
label: `Added marker ${id}`,
|
|
2147
|
+
undo: () => adapter.setMarkers((all) => all.filter((m) => m.id !== id)),
|
|
2148
|
+
redo: () => adapter.setMarkers((all) => [...all, marker])
|
|
2149
|
+
});
|
|
2150
|
+
return textResult(`Added marker ${id} at ${marker.position.lat.toFixed(4)},${marker.position.lng.toFixed(4)}`, marker);
|
|
2151
|
+
},
|
|
2152
|
+
mTarget
|
|
2153
|
+
);
|
|
2154
|
+
reg(
|
|
2155
|
+
"map_update_marker",
|
|
2156
|
+
"Update a marker. Only provided fields change \u2014 update lat/lng repeatedly to drive a live track.",
|
|
2157
|
+
{
|
|
2158
|
+
id: { type: "string" },
|
|
2159
|
+
lat: { type: "number" },
|
|
2160
|
+
lng: { type: "number" },
|
|
2161
|
+
label: { type: "string" },
|
|
2162
|
+
color: { type: "string" },
|
|
2163
|
+
icon: { type: "string" },
|
|
2164
|
+
draggable: { type: "boolean" }
|
|
2165
|
+
},
|
|
2166
|
+
["id"],
|
|
2167
|
+
(args) => {
|
|
2168
|
+
const id = str2(args.id);
|
|
2169
|
+
const prev = adapter.getMarkers().find((m) => m.id === id);
|
|
2170
|
+
if (!prev) {
|
|
2171
|
+
return errorResult(`No marker with id ${id}`);
|
|
2172
|
+
}
|
|
2173
|
+
const next = {
|
|
2174
|
+
...prev,
|
|
2175
|
+
position: {
|
|
2176
|
+
lat: args.lat !== void 0 ? num2(args.lat) : prev.position.lat,
|
|
2177
|
+
lng: args.lng !== void 0 ? num2(args.lng) : prev.position.lng
|
|
2178
|
+
},
|
|
2179
|
+
...args.label !== void 0 ? { label: str2(args.label) } : {},
|
|
2180
|
+
...args.color !== void 0 ? { color: str2(args.color) } : {},
|
|
2181
|
+
...args.icon !== void 0 ? { icon: str2(args.icon) } : {},
|
|
2182
|
+
...args.draggable !== void 0 ? { draggable: !!args.draggable } : {}
|
|
2183
|
+
};
|
|
2184
|
+
adapter.setMarkers((all) => all.map((m) => m.id === id ? next : m));
|
|
2185
|
+
fancyAutoCommon.pushUndoEntry(agent.id, {
|
|
2186
|
+
timestamp: Date.now(),
|
|
2187
|
+
bridgeId: "map",
|
|
2188
|
+
action: "map_update_marker",
|
|
2189
|
+
label: `Updated marker ${id}`,
|
|
2190
|
+
undo: () => adapter.setMarkers((all) => all.map((m) => m.id === id ? prev : m)),
|
|
2191
|
+
redo: () => adapter.setMarkers((all) => all.map((m) => m.id === id ? next : m))
|
|
2192
|
+
});
|
|
2193
|
+
return textResult(`Updated marker ${id}`, next);
|
|
2194
|
+
},
|
|
2195
|
+
mTarget
|
|
2196
|
+
);
|
|
2197
|
+
reg(
|
|
2198
|
+
"map_remove_marker",
|
|
2199
|
+
"Remove a marker by id.",
|
|
2200
|
+
{ id: { type: "string" } },
|
|
2201
|
+
["id"],
|
|
2202
|
+
(args) => {
|
|
2203
|
+
const id = str2(args.id);
|
|
2204
|
+
const prev = adapter.getMarkers().find((m) => m.id === id);
|
|
2205
|
+
if (!prev) {
|
|
2206
|
+
return errorResult(`No marker with id ${id}`);
|
|
2207
|
+
}
|
|
2208
|
+
adapter.setMarkers((all) => all.filter((m) => m.id !== id));
|
|
2209
|
+
fancyAutoCommon.pushUndoEntry(agent.id, {
|
|
2210
|
+
timestamp: Date.now(),
|
|
2211
|
+
bridgeId: "map",
|
|
2212
|
+
action: "map_remove_marker",
|
|
2213
|
+
label: `Removed marker ${id}`,
|
|
2214
|
+
undo: () => adapter.setMarkers((all) => [...all, prev]),
|
|
2215
|
+
redo: () => adapter.setMarkers((all) => all.filter((m) => m.id !== id))
|
|
2216
|
+
});
|
|
2217
|
+
return textResult(`Removed marker ${id}`);
|
|
2218
|
+
},
|
|
2219
|
+
mTarget
|
|
2220
|
+
);
|
|
2221
|
+
reg(
|
|
2222
|
+
"map_select",
|
|
2223
|
+
"Select a marker (or pass no id / null to clear the selection).",
|
|
2224
|
+
{ id: { type: "string" } },
|
|
2225
|
+
[],
|
|
2226
|
+
(args) => {
|
|
2227
|
+
const prev = adapter.getSelected();
|
|
2228
|
+
const id = args.id === void 0 || args.id === null ? null : str2(args.id);
|
|
2229
|
+
if (id !== null && !adapter.getMarkers().some((m) => m.id === id)) {
|
|
2230
|
+
return errorResult(`No marker with id ${id}`);
|
|
2231
|
+
}
|
|
2232
|
+
adapter.setSelected(id);
|
|
2233
|
+
fancyAutoCommon.pushUndoEntry(agent.id, {
|
|
2234
|
+
timestamp: Date.now(),
|
|
2235
|
+
bridgeId: "map",
|
|
2236
|
+
action: "map_select",
|
|
2237
|
+
label: id ? `Selected ${id}` : "Cleared selection",
|
|
2238
|
+
undo: () => adapter.setSelected(prev),
|
|
2239
|
+
redo: () => adapter.setSelected(id)
|
|
2240
|
+
});
|
|
2241
|
+
return textResult(id ? `Selected marker ${id}` : "Cleared selection", { selectedId: id });
|
|
2242
|
+
},
|
|
2243
|
+
mTarget
|
|
2244
|
+
);
|
|
2245
|
+
reg(
|
|
2246
|
+
"map_start_track",
|
|
2247
|
+
"Make the camera follow a marker as its position updates (live tracking). Requires the host to wire setFollow.",
|
|
2248
|
+
{ id: { type: "string" } },
|
|
2249
|
+
["id"],
|
|
2250
|
+
(args) => {
|
|
2251
|
+
if (!adapter.setFollow) {
|
|
2252
|
+
return errorResult("Host did not wire setFollow (pass the map's `follow` setter).");
|
|
2253
|
+
}
|
|
2254
|
+
const id = str2(args.id);
|
|
2255
|
+
if (!adapter.getMarkers().some((m) => m.id === id)) {
|
|
2256
|
+
return errorResult(`No marker with id ${id}`);
|
|
2257
|
+
}
|
|
2258
|
+
adapter.setFollow(id);
|
|
2259
|
+
return textResult(`Camera now following ${id}`, { follow: id });
|
|
2260
|
+
},
|
|
2261
|
+
mTarget
|
|
2262
|
+
);
|
|
2263
|
+
reg(
|
|
2264
|
+
"map_stop_track",
|
|
2265
|
+
"Stop following any marker (releases the camera). Requires the host to wire setFollow.",
|
|
2266
|
+
{},
|
|
2267
|
+
[],
|
|
2268
|
+
() => {
|
|
2269
|
+
if (!adapter.setFollow) {
|
|
2270
|
+
return errorResult("Host did not wire setFollow.");
|
|
2271
|
+
}
|
|
2272
|
+
adapter.setFollow(null);
|
|
2273
|
+
return textResult("Camera released (no longer following).", { follow: null });
|
|
2274
|
+
}
|
|
2275
|
+
);
|
|
2276
|
+
return {
|
|
2277
|
+
id: "map",
|
|
2278
|
+
title: "Map",
|
|
2279
|
+
dispose: () => {
|
|
2280
|
+
for (const d of disposers) d();
|
|
2281
|
+
}
|
|
2282
|
+
};
|
|
2283
|
+
}
|
|
2284
|
+
|
|
2285
|
+
// src/bridges/files.ts
|
|
2286
|
+
var DEFAULT_AGENT9 = { id: "agent", name: "Agent", color: "#0ea5e9" };
|
|
2287
|
+
var str3 = (v, fallback = "") => typeof v === "string" ? v : fallback;
|
|
2288
|
+
var num3 = (v, fallback) => typeof v === "number" && Number.isFinite(v) ? v : 0;
|
|
2289
|
+
var asPaths = (v) => {
|
|
2290
|
+
if (typeof v === "string") {
|
|
2291
|
+
return [v];
|
|
2292
|
+
}
|
|
2293
|
+
if (Array.isArray(v)) {
|
|
2294
|
+
return v.filter((x) => typeof x === "string");
|
|
2295
|
+
}
|
|
2296
|
+
return [];
|
|
2297
|
+
};
|
|
2298
|
+
function registerFilesBridge(host, options) {
|
|
2299
|
+
const { adapter } = options;
|
|
2300
|
+
const agent = { ...DEFAULT_AGENT9, ...options.agent ?? {} };
|
|
2301
|
+
const disposers = [];
|
|
2302
|
+
ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
|
|
2303
|
+
const fTarget = (args, _result) => ({
|
|
2304
|
+
kind: "files",
|
|
2305
|
+
elementId: args?.path ?? void 0
|
|
2306
|
+
});
|
|
2307
|
+
const reg = (name, description, properties, required, handler, resolveTarget) => {
|
|
2308
|
+
const wrapped = async (args) => {
|
|
2309
|
+
try {
|
|
2310
|
+
return await handler(args);
|
|
2311
|
+
} catch (e) {
|
|
2312
|
+
return errorResult(e instanceof Error ? e.message : String(e));
|
|
2313
|
+
}
|
|
2314
|
+
};
|
|
2315
|
+
const final = resolveTarget ? wrapToolWithActivity(wrapped, {
|
|
2316
|
+
toolName: name,
|
|
2317
|
+
agent: { id: agent.id, name: agent.name, color: agent.color },
|
|
2318
|
+
kind: "files",
|
|
2319
|
+
resolveTarget: ({ args, result }) => resolveTarget(args, result)
|
|
2320
|
+
}) : wrapped;
|
|
2321
|
+
disposers.push(
|
|
2322
|
+
host.registerTool(
|
|
2323
|
+
{
|
|
2324
|
+
name,
|
|
2325
|
+
description,
|
|
2326
|
+
inputSchema: {
|
|
2327
|
+
type: "object",
|
|
2328
|
+
properties,
|
|
2329
|
+
required,
|
|
2330
|
+
additionalProperties: false
|
|
2331
|
+
}
|
|
2332
|
+
},
|
|
2333
|
+
final
|
|
2334
|
+
)
|
|
2335
|
+
);
|
|
2336
|
+
};
|
|
2337
|
+
reg(
|
|
2338
|
+
"files_get_state",
|
|
2339
|
+
"Get the file browser's current directory, selected path(s), and expanded folders.",
|
|
2340
|
+
{},
|
|
2341
|
+
[],
|
|
2342
|
+
() => {
|
|
2343
|
+
const state = {
|
|
2344
|
+
path: adapter.getPath(),
|
|
2345
|
+
selected: adapter.getSelection(),
|
|
2346
|
+
expanded: adapter.getExpanded()
|
|
2347
|
+
};
|
|
2348
|
+
return textResult(JSON.stringify(state, null, 2), state);
|
|
2349
|
+
}
|
|
2350
|
+
);
|
|
2351
|
+
reg(
|
|
2352
|
+
"files_list",
|
|
2353
|
+
"List the direct children of a folder (files + subfolders). Omit `path` for the current directory. Loads lazily from the host's provider/snapshot \u2014 never an eager tree walk.",
|
|
2354
|
+
{ path: { type: "string", description: "Folder path to list; defaults to the current directory." } },
|
|
2355
|
+
[],
|
|
2356
|
+
async (args) => {
|
|
2357
|
+
const path = args.path !== void 0 ? str3(args.path) : adapter.getPath();
|
|
2358
|
+
const entries = await adapter.listChildren(path);
|
|
2359
|
+
const summary = entries.map((e) => ({
|
|
2360
|
+
path: e.path,
|
|
2361
|
+
name: e.name,
|
|
2362
|
+
kind: e.kind,
|
|
2363
|
+
...e.size !== void 0 ? { size: e.size } : {},
|
|
2364
|
+
...e.mtime !== void 0 ? { mtime: e.mtime } : {}
|
|
2365
|
+
}));
|
|
2366
|
+
const text = summary.map((e) => `${e.kind === "dir" ? "\u{1F4C1}" : "\u{1F4C4}"} ${e.path}`).join("\n") || `(empty: ${path})`;
|
|
2367
|
+
return textResult(text, { path, entries: summary });
|
|
2368
|
+
}
|
|
2369
|
+
);
|
|
2370
|
+
reg(
|
|
2371
|
+
"files_navigate",
|
|
2372
|
+
"Set the current directory (as if the user clicked a breadcrumb or opened a folder).",
|
|
2373
|
+
{ path: { type: "string" } },
|
|
2374
|
+
["path"],
|
|
2375
|
+
(args) => {
|
|
2376
|
+
const path = str3(args.path);
|
|
2377
|
+
const prev = adapter.getPath();
|
|
2378
|
+
adapter.setPath(path);
|
|
2379
|
+
fancyAutoCommon.pushUndoEntry(agent.id, {
|
|
2380
|
+
timestamp: Date.now(),
|
|
2381
|
+
bridgeId: "files",
|
|
2382
|
+
action: "files_navigate",
|
|
2383
|
+
label: `Navigated to ${path}`,
|
|
2384
|
+
undo: () => adapter.setPath(prev),
|
|
2385
|
+
redo: () => adapter.setPath(path)
|
|
2386
|
+
});
|
|
2387
|
+
return textResult(`Current directory \u2192 ${path}`, { path });
|
|
2388
|
+
},
|
|
2389
|
+
fTarget
|
|
2390
|
+
);
|
|
2391
|
+
reg(
|
|
2392
|
+
"files_expand",
|
|
2393
|
+
"Expand a folder in the tree (loads its children if needed).",
|
|
2394
|
+
{ path: { type: "string" } },
|
|
2395
|
+
["path"],
|
|
2396
|
+
(args) => {
|
|
2397
|
+
const path = str3(args.path);
|
|
2398
|
+
if (adapter.getExpanded().includes(path)) {
|
|
2399
|
+
return textResult(`${path} already expanded`, { path, expanded: true });
|
|
2400
|
+
}
|
|
2401
|
+
adapter.setExpanded((prev) => [...prev, path]);
|
|
2402
|
+
fancyAutoCommon.pushUndoEntry(agent.id, {
|
|
2403
|
+
timestamp: Date.now(),
|
|
2404
|
+
bridgeId: "files",
|
|
2405
|
+
action: "files_expand",
|
|
2406
|
+
label: `Expanded ${path}`,
|
|
2407
|
+
undo: () => adapter.setExpanded((prev) => prev.filter((p) => p !== path)),
|
|
2408
|
+
redo: () => adapter.setExpanded((prev) => prev.includes(path) ? prev : [...prev, path])
|
|
2409
|
+
});
|
|
2410
|
+
return textResult(`Expanded ${path}`, { path, expanded: true });
|
|
2411
|
+
},
|
|
2412
|
+
fTarget
|
|
2413
|
+
);
|
|
2414
|
+
reg(
|
|
2415
|
+
"files_collapse",
|
|
2416
|
+
"Collapse a folder in the tree.",
|
|
2417
|
+
{ path: { type: "string" } },
|
|
2418
|
+
["path"],
|
|
2419
|
+
(args) => {
|
|
2420
|
+
const path = str3(args.path);
|
|
2421
|
+
if (!adapter.getExpanded().includes(path)) {
|
|
2422
|
+
return textResult(`${path} already collapsed`, { path, expanded: false });
|
|
2423
|
+
}
|
|
2424
|
+
adapter.setExpanded((prev) => prev.filter((p) => p !== path));
|
|
2425
|
+
fancyAutoCommon.pushUndoEntry(agent.id, {
|
|
2426
|
+
timestamp: Date.now(),
|
|
2427
|
+
bridgeId: "files",
|
|
2428
|
+
action: "files_collapse",
|
|
2429
|
+
label: `Collapsed ${path}`,
|
|
2430
|
+
undo: () => adapter.setExpanded((prev) => prev.includes(path) ? prev : [...prev, path]),
|
|
2431
|
+
redo: () => adapter.setExpanded((prev) => prev.filter((p) => p !== path))
|
|
2432
|
+
});
|
|
2433
|
+
return textResult(`Collapsed ${path}`, { path, expanded: false });
|
|
2434
|
+
},
|
|
2435
|
+
fTarget
|
|
2436
|
+
);
|
|
2437
|
+
reg(
|
|
2438
|
+
"files_select",
|
|
2439
|
+
"Set the selection to the given path(s). Pass a single `path`, or `paths` for a multi-select browser; either empty clears the selection.",
|
|
2440
|
+
{
|
|
2441
|
+
path: { type: "string", description: "A single path to select." },
|
|
2442
|
+
paths: { type: "array", items: { type: "string" }, description: "Multiple paths (multi-select browsers)." }
|
|
2443
|
+
},
|
|
2444
|
+
[],
|
|
2445
|
+
(args) => {
|
|
2446
|
+
const next = args.paths !== void 0 ? asPaths(args.paths) : asPaths(args.path);
|
|
2447
|
+
const prev = adapter.getSelection();
|
|
2448
|
+
adapter.setSelection(next);
|
|
2449
|
+
fancyAutoCommon.pushUndoEntry(agent.id, {
|
|
2450
|
+
timestamp: Date.now(),
|
|
2451
|
+
bridgeId: "files",
|
|
2452
|
+
action: "files_select",
|
|
2453
|
+
label: next.length ? `Selected ${next.join(", ")}` : "Cleared selection",
|
|
2454
|
+
undo: () => adapter.setSelection(prev),
|
|
2455
|
+
redo: () => adapter.setSelection(next)
|
|
2456
|
+
});
|
|
2457
|
+
return textResult(next.length ? `Selected ${next.join(", ")}` : "Cleared selection", {
|
|
2458
|
+
selected: next
|
|
2459
|
+
});
|
|
2460
|
+
},
|
|
2461
|
+
fTarget
|
|
2462
|
+
);
|
|
2463
|
+
reg(
|
|
2464
|
+
"files_request_snapshot",
|
|
2465
|
+
"Request a fresh snapshot subtree rooted at `path` (snapshot mode) \u2014 e.g. to pull a remote machine's current tree. Requires the host to wire requestSnapshot.",
|
|
2466
|
+
{
|
|
2467
|
+
path: { type: "string", description: "Root of the subtree; defaults to the current directory." },
|
|
2468
|
+
depth: { type: "number", description: "How many levels deep to materialize (host-defined default)." }
|
|
2469
|
+
},
|
|
2470
|
+
[],
|
|
2471
|
+
async (args) => {
|
|
2472
|
+
if (!adapter.requestSnapshot) {
|
|
2473
|
+
return errorResult("Host did not wire requestSnapshot (snapshot mode not enabled).");
|
|
2474
|
+
}
|
|
2475
|
+
const path = args.path !== void 0 ? str3(args.path) : adapter.getPath();
|
|
2476
|
+
const depth = args.depth !== void 0 ? num3(args.depth) : void 0;
|
|
2477
|
+
const tree = await adapter.requestSnapshot(path, depth);
|
|
2478
|
+
const count = Array.isArray(tree) ? tree.length : 0;
|
|
2479
|
+
return textResult(`Snapshot of ${path}: ${count} top-level entr${count === 1 ? "y" : "ies"}.`, {
|
|
2480
|
+
path,
|
|
2481
|
+
snapshot: tree
|
|
2482
|
+
});
|
|
2483
|
+
},
|
|
2484
|
+
fTarget
|
|
2485
|
+
);
|
|
2486
|
+
return {
|
|
2487
|
+
id: "files",
|
|
2488
|
+
title: "Files",
|
|
2489
|
+
dispose: () => {
|
|
2490
|
+
for (const d of disposers) d();
|
|
2491
|
+
}
|
|
2492
|
+
};
|
|
2493
|
+
}
|
|
2494
|
+
|
|
1958
2495
|
// src/bridges/terminal.ts
|
|
1959
|
-
var
|
|
2496
|
+
var DEFAULT_AGENT10 = { id: "agent", name: "Agent", color: "#a855f7" };
|
|
1960
2497
|
var truncate = (s, n = 60) => s.length > n ? s.slice(0, n) + "\u2026" : s;
|
|
1961
2498
|
function registerTerminalBridge(host, options) {
|
|
1962
|
-
const agent = { ...
|
|
2499
|
+
const agent = { ...DEFAULT_AGENT10, ...options.agent ?? {} };
|
|
1963
2500
|
const pendingMode = options.pendingMode ?? false;
|
|
1964
2501
|
const screenId = options.screenId ?? options.adapter?.screenId;
|
|
1965
2502
|
const disposers = [];
|
|
@@ -2224,10 +2761,10 @@ function registerTerminalBridge(host, options) {
|
|
|
2224
2761
|
}
|
|
2225
2762
|
|
|
2226
2763
|
// src/bridges/navigation.ts
|
|
2227
|
-
var
|
|
2764
|
+
var DEFAULT_AGENT11 = { id: "agent", name: "Agent", color: "#a855f7" };
|
|
2228
2765
|
function registerNavigationBridge(host, options) {
|
|
2229
2766
|
const { adapter } = options;
|
|
2230
|
-
const agent = { ...
|
|
2767
|
+
const agent = { ...DEFAULT_AGENT11, ...options.agent ?? {} };
|
|
2231
2768
|
const pendingMode = options.pendingMode ?? true;
|
|
2232
2769
|
const disposers = [];
|
|
2233
2770
|
ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
|
|
@@ -2432,12 +2969,12 @@ function registerNavigationBridge(host, options) {
|
|
|
2432
2969
|
}
|
|
2433
2970
|
|
|
2434
2971
|
// src/bridges/catalog.ts
|
|
2435
|
-
var
|
|
2436
|
-
var
|
|
2437
|
-
var
|
|
2972
|
+
var DEFAULT_AGENT12 = { id: "agent", name: "Agent", color: "#a855f7" };
|
|
2973
|
+
var str4 = (v, fallback = "") => typeof v === "string" ? v : fallback;
|
|
2974
|
+
var num4 = (v, fallback = 0) => typeof v === "number" && Number.isFinite(v) ? v : fallback;
|
|
2438
2975
|
function registerCatalogBridge(host, options) {
|
|
2439
2976
|
const { adapter } = options;
|
|
2440
|
-
const agent = { ...
|
|
2977
|
+
const agent = { ...DEFAULT_AGENT12, ...options.agent ?? {} };
|
|
2441
2978
|
const pendingMode = options.pendingMode ?? true;
|
|
2442
2979
|
const catalogId = adapter.id ?? "catalog";
|
|
2443
2980
|
const disposers = [];
|
|
@@ -2507,7 +3044,7 @@ function registerCatalogBridge(host, options) {
|
|
|
2507
3044
|
{ id: { type: "string" }, withTrashed: { type: "boolean" } },
|
|
2508
3045
|
["id"],
|
|
2509
3046
|
async (args) => {
|
|
2510
|
-
const id =
|
|
3047
|
+
const id = str4(args.id);
|
|
2511
3048
|
const product = await adapter.products.find(id, { withTrashed: args.withTrashed === true });
|
|
2512
3049
|
if (!product) return errorResult(`No product with id ${id}`);
|
|
2513
3050
|
const prices = await adapter.prices.forProduct(id, { withTrashed: args.withTrashed === true });
|
|
@@ -2523,7 +3060,7 @@ function registerCatalogBridge(host, options) {
|
|
|
2523
3060
|
[],
|
|
2524
3061
|
async (args) => {
|
|
2525
3062
|
const withTrashed = args.withTrashed === true;
|
|
2526
|
-
const prices = args.productId !== void 0 ? await adapter.prices.forProduct(
|
|
3063
|
+
const prices = args.productId !== void 0 ? await adapter.prices.forProduct(str4(args.productId), { withTrashed }) : await adapter.prices.all({ withTrashed });
|
|
2527
3064
|
const list = prices.map((p) => ({
|
|
2528
3065
|
id: p.id,
|
|
2529
3066
|
productId: p.productId,
|
|
@@ -2549,13 +3086,13 @@ function registerCatalogBridge(host, options) {
|
|
|
2549
3086
|
},
|
|
2550
3087
|
["name"],
|
|
2551
3088
|
async (args) => {
|
|
2552
|
-
const name =
|
|
3089
|
+
const name = str4(args.name);
|
|
2553
3090
|
if (!name) return errorResult("name is required.");
|
|
2554
3091
|
const product = await adapter.createProduct({
|
|
2555
3092
|
name,
|
|
2556
|
-
...args.description !== void 0 ? { description:
|
|
3093
|
+
...args.description !== void 0 ? { description: str4(args.description) } : {},
|
|
2557
3094
|
...args.active !== void 0 ? { active: args.active === true } : {},
|
|
2558
|
-
...args.lookupKey !== void 0 ? { lookupKey:
|
|
3095
|
+
...args.lookupKey !== void 0 ? { lookupKey: str4(args.lookupKey) } : {},
|
|
2559
3096
|
...args.metadata && typeof args.metadata === "object" ? { metadata: args.metadata } : {}
|
|
2560
3097
|
});
|
|
2561
3098
|
fancyAutoCommon.pushUndoEntry(agent.id, {
|
|
@@ -2568,7 +3105,7 @@ function registerCatalogBridge(host, options) {
|
|
|
2568
3105
|
});
|
|
2569
3106
|
return textResult(`Created product ${product.id} (${product.name})`, product);
|
|
2570
3107
|
},
|
|
2571
|
-
(args) => target(void 0, `create product ${
|
|
3108
|
+
(args) => target(void 0, `create product ${str4(args.name)}`)
|
|
2572
3109
|
);
|
|
2573
3110
|
reg(
|
|
2574
3111
|
"catalog_create_price",
|
|
@@ -2585,19 +3122,19 @@ function registerCatalogBridge(host, options) {
|
|
|
2585
3122
|
},
|
|
2586
3123
|
["productId", "currency", "unitAmount", "type"],
|
|
2587
3124
|
async (args) => {
|
|
2588
|
-
const productId =
|
|
3125
|
+
const productId = str4(args.productId);
|
|
2589
3126
|
const product = await adapter.products.find(productId);
|
|
2590
3127
|
if (!product) return errorResult(`No product with id ${productId}`);
|
|
2591
|
-
const type =
|
|
3128
|
+
const type = str4(args.type);
|
|
2592
3129
|
if (type !== "recurring" && type !== "one_time") return errorResult("type must be 'recurring' or 'one_time'.");
|
|
2593
3130
|
const price = await adapter.createPrice({
|
|
2594
3131
|
productId,
|
|
2595
|
-
currency:
|
|
2596
|
-
unitAmount:
|
|
3132
|
+
currency: str4(args.currency),
|
|
3133
|
+
unitAmount: num4(args.unitAmount),
|
|
2597
3134
|
type,
|
|
2598
|
-
...args.recurringInterval !== void 0 ? { recurringInterval:
|
|
2599
|
-
...args.nickname !== void 0 ? { nickname:
|
|
2600
|
-
...args.lookupKey !== void 0 ? { lookupKey:
|
|
3135
|
+
...args.recurringInterval !== void 0 ? { recurringInterval: str4(args.recurringInterval) } : {},
|
|
3136
|
+
...args.nickname !== void 0 ? { nickname: str4(args.nickname) } : {},
|
|
3137
|
+
...args.lookupKey !== void 0 ? { lookupKey: str4(args.lookupKey) } : {},
|
|
2601
3138
|
...args.metadata && typeof args.metadata === "object" ? { metadata: args.metadata } : {}
|
|
2602
3139
|
});
|
|
2603
3140
|
fancyAutoCommon.pushUndoEntry(agent.id, {
|
|
@@ -2610,7 +3147,7 @@ function registerCatalogBridge(host, options) {
|
|
|
2610
3147
|
});
|
|
2611
3148
|
return textResult(`Created ${type} price ${price.id} on ${productId}`, price);
|
|
2612
3149
|
},
|
|
2613
|
-
(args) => target(
|
|
3150
|
+
(args) => target(str4(args.productId), `create price on ${str4(args.productId)}`)
|
|
2614
3151
|
);
|
|
2615
3152
|
reg(
|
|
2616
3153
|
"catalog_delete_product",
|
|
@@ -2618,7 +3155,7 @@ function registerCatalogBridge(host, options) {
|
|
|
2618
3155
|
{ id: { type: "string" }, confirm: { type: "boolean" } },
|
|
2619
3156
|
["id"],
|
|
2620
3157
|
async (args) => {
|
|
2621
|
-
const id =
|
|
3158
|
+
const id = str4(args.id);
|
|
2622
3159
|
const product = await adapter.products.find(id, { withTrashed: true });
|
|
2623
3160
|
if (!product) return errorResult(`No product with id ${id}`);
|
|
2624
3161
|
const blocked = await guardDestructive("catalog_delete_product", id, product.name, args.confirm === true);
|
|
@@ -2635,7 +3172,7 @@ function registerCatalogBridge(host, options) {
|
|
|
2635
3172
|
});
|
|
2636
3173
|
return textResult(`Deleted product ${id}`, { id });
|
|
2637
3174
|
},
|
|
2638
|
-
(args) => target(
|
|
3175
|
+
(args) => target(str4(args.id), `delete product ${str4(args.id)}`)
|
|
2639
3176
|
);
|
|
2640
3177
|
reg(
|
|
2641
3178
|
"catalog_delete_price",
|
|
@@ -2643,7 +3180,7 @@ function registerCatalogBridge(host, options) {
|
|
|
2643
3180
|
{ id: { type: "string" }, confirm: { type: "boolean" } },
|
|
2644
3181
|
["id"],
|
|
2645
3182
|
async (args) => {
|
|
2646
|
-
const id =
|
|
3183
|
+
const id = str4(args.id);
|
|
2647
3184
|
const price = await adapter.prices.find(id, { withTrashed: true });
|
|
2648
3185
|
if (!price) return errorResult(`No price with id ${id}`);
|
|
2649
3186
|
const blocked = await guardDestructive("catalog_delete_price", id, id, args.confirm === true);
|
|
@@ -2660,7 +3197,7 @@ function registerCatalogBridge(host, options) {
|
|
|
2660
3197
|
});
|
|
2661
3198
|
return textResult(`Deleted price ${id}`, { id });
|
|
2662
3199
|
},
|
|
2663
|
-
(args) => target(
|
|
3200
|
+
(args) => target(str4(args.id), `delete price ${str4(args.id)}`)
|
|
2664
3201
|
);
|
|
2665
3202
|
reg(
|
|
2666
3203
|
"catalog_sync_product",
|
|
@@ -2669,13 +3206,13 @@ function registerCatalogBridge(host, options) {
|
|
|
2669
3206
|
["id"],
|
|
2670
3207
|
async (args) => {
|
|
2671
3208
|
if (!adapter.syncProductAndPrices) return errorResult("Host did not wire Stripe sync.");
|
|
2672
|
-
const id =
|
|
3209
|
+
const id = str4(args.id);
|
|
2673
3210
|
const product = await adapter.products.find(id);
|
|
2674
3211
|
if (!product) return errorResult(`No product with id ${id}`);
|
|
2675
3212
|
const synced = await adapter.syncProductAndPrices(product);
|
|
2676
3213
|
return textResult(`Synced product ${id} to Stripe (${synced.externalId ?? "no external id"})`, synced);
|
|
2677
3214
|
},
|
|
2678
|
-
(args) => target(
|
|
3215
|
+
(args) => target(str4(args.id), `sync product ${str4(args.id)}`)
|
|
2679
3216
|
);
|
|
2680
3217
|
reg(
|
|
2681
3218
|
"catalog_test_connection",
|
|
@@ -2702,13 +3239,13 @@ function registerCatalogBridge(host, options) {
|
|
|
2702
3239
|
},
|
|
2703
3240
|
["priceId", "successUrl", "cancelUrl"],
|
|
2704
3241
|
async (args) => {
|
|
2705
|
-
const priceId =
|
|
3242
|
+
const priceId = str4(args.priceId);
|
|
2706
3243
|
const price = await adapter.prices.find(priceId);
|
|
2707
3244
|
if (!price) return errorResult(`No price with id ${priceId}`);
|
|
2708
3245
|
const checkoutArgs = {
|
|
2709
|
-
successUrl:
|
|
2710
|
-
cancelUrl:
|
|
2711
|
-
...args.customer !== void 0 ? { customer:
|
|
3246
|
+
successUrl: str4(args.successUrl),
|
|
3247
|
+
cancelUrl: str4(args.cancelUrl),
|
|
3248
|
+
...args.customer !== void 0 ? { customer: str4(args.customer) } : {},
|
|
2712
3249
|
...args.metadata && typeof args.metadata === "object" ? { metadata: args.metadata } : {}
|
|
2713
3250
|
};
|
|
2714
3251
|
let url;
|
|
@@ -2717,11 +3254,11 @@ function registerCatalogBridge(host, options) {
|
|
|
2717
3254
|
url = await adapter.getSubscriptionCheckoutUrl(price, checkoutArgs);
|
|
2718
3255
|
} else {
|
|
2719
3256
|
if (!adapter.getOneTimeCheckoutUrl) return errorResult("Host did not wire one-time checkout.");
|
|
2720
|
-
url = await adapter.getOneTimeCheckoutUrl(price, { ...checkoutArgs, quantity:
|
|
3257
|
+
url = await adapter.getOneTimeCheckoutUrl(price, { ...checkoutArgs, quantity: num4(args.quantity, 1) });
|
|
2721
3258
|
}
|
|
2722
3259
|
return textResult(url || "(no url)", { priceId, type: price.type, url });
|
|
2723
3260
|
},
|
|
2724
|
-
(args) => target(
|
|
3261
|
+
(args) => target(str4(args.priceId), `checkout ${str4(args.priceId)}`)
|
|
2725
3262
|
);
|
|
2726
3263
|
return {
|
|
2727
3264
|
id: `catalog:${catalogId}`,
|
|
@@ -2733,12 +3270,12 @@ function registerCatalogBridge(host, options) {
|
|
|
2733
3270
|
}
|
|
2734
3271
|
|
|
2735
3272
|
// src/bridges/features.ts
|
|
2736
|
-
var
|
|
2737
|
-
var
|
|
2738
|
-
var
|
|
3273
|
+
var DEFAULT_AGENT13 = { id: "agent", name: "Agent", color: "#a855f7" };
|
|
3274
|
+
var str5 = (v, fallback = "") => typeof v === "string" ? v : fallback;
|
|
3275
|
+
var num5 = (v, fallback = 0) => typeof v === "number" && Number.isFinite(v) ? v : fallback;
|
|
2739
3276
|
function registerFeaturesBridge(host, options) {
|
|
2740
3277
|
const { adapter } = options;
|
|
2741
|
-
const agent = { ...
|
|
3278
|
+
const agent = { ...DEFAULT_AGENT13, ...options.agent ?? {} };
|
|
2742
3279
|
const pendingMode = options.pendingMode ?? true;
|
|
2743
3280
|
const featuresId = adapter.id ?? "features";
|
|
2744
3281
|
const disposers = [];
|
|
@@ -2799,7 +3336,7 @@ function registerFeaturesBridge(host, options) {
|
|
|
2799
3336
|
{ feature: { type: "string" }, subject: { description: "Opaque subject." }, context: { description: "Optional context." } },
|
|
2800
3337
|
["feature"],
|
|
2801
3338
|
async (args) => {
|
|
2802
|
-
const feature =
|
|
3339
|
+
const feature = str5(args.feature);
|
|
2803
3340
|
const allowed = await adapter.canAccess(feature, args.subject, args.context);
|
|
2804
3341
|
const remaining = await adapter.remaining(feature, args.subject, args.context);
|
|
2805
3342
|
const out = { feature, allowed, remaining };
|
|
@@ -2814,7 +3351,7 @@ function registerFeaturesBridge(host, options) {
|
|
|
2814
3351
|
["feature"],
|
|
2815
3352
|
async (args) => {
|
|
2816
3353
|
if (!adapter.explain) return errorResult("Host did not wire explain().");
|
|
2817
|
-
const result = await adapter.explain(
|
|
3354
|
+
const result = await adapter.explain(str5(args.feature), args.subject, args.context);
|
|
2818
3355
|
return textResult(JSON.stringify(result, null, 2), result);
|
|
2819
3356
|
},
|
|
2820
3357
|
false
|
|
@@ -2843,15 +3380,15 @@ function registerFeaturesBridge(host, options) {
|
|
|
2843
3380
|
},
|
|
2844
3381
|
["key"],
|
|
2845
3382
|
(args) => {
|
|
2846
|
-
const key =
|
|
3383
|
+
const key = str5(args.key);
|
|
2847
3384
|
if (!key) return errorResult("key is required.");
|
|
2848
3385
|
const existed = adapter.registryKeys().includes(key);
|
|
2849
3386
|
const definition = {
|
|
2850
|
-
...args.name !== void 0 ? { name:
|
|
2851
|
-
...args.description !== void 0 ? { description:
|
|
2852
|
-
...args.type !== void 0 ? { type:
|
|
3387
|
+
...args.name !== void 0 ? { name: str5(args.name) } : {},
|
|
3388
|
+
...args.description !== void 0 ? { description: str5(args.description) } : {},
|
|
3389
|
+
...args.type !== void 0 ? { type: str5(args.type) } : {},
|
|
2853
3390
|
...args.enabled !== void 0 ? { enabled: args.enabled === true } : {},
|
|
2854
|
-
...args.limit !== void 0 ? { limit:
|
|
3391
|
+
...args.limit !== void 0 ? { limit: num5(args.limit) } : {}
|
|
2855
3392
|
};
|
|
2856
3393
|
adapter.registerFeature(key, definition);
|
|
2857
3394
|
fancyAutoCommon.pushUndoEntry(agent.id, {
|
|
@@ -2866,7 +3403,7 @@ function registerFeaturesBridge(host, options) {
|
|
|
2866
3403
|
});
|
|
2867
3404
|
return textResult(`${existed ? "Redefined" : "Defined"} feature ${key} (${definition.type ?? "boolean"})`, { key, definition });
|
|
2868
3405
|
},
|
|
2869
|
-
(args) => target(
|
|
3406
|
+
(args) => target(str5(args.key), `define ${str5(args.key)}`)
|
|
2870
3407
|
);
|
|
2871
3408
|
reg(
|
|
2872
3409
|
"features_grant",
|
|
@@ -2874,7 +3411,7 @@ function registerFeaturesBridge(host, options) {
|
|
|
2874
3411
|
{ subject: { description: "Opaque subject." }, group: { type: "string", description: "Feature group key." }, confirm: { type: "boolean" } },
|
|
2875
3412
|
["subject", "group"],
|
|
2876
3413
|
async (args) => {
|
|
2877
|
-
const groupKey =
|
|
3414
|
+
const groupKey = str5(args.group);
|
|
2878
3415
|
if (!groupKey) return errorResult("group is required.");
|
|
2879
3416
|
const blocked = await guardGrant("features_grant", args.subject, groupKey, args.confirm === true);
|
|
2880
3417
|
if (blocked) return blocked;
|
|
@@ -2893,7 +3430,7 @@ function registerFeaturesBridge(host, options) {
|
|
|
2893
3430
|
});
|
|
2894
3431
|
return textResult(`Granted group ${groupKey}`, { subject: args.subject, group: groupKey });
|
|
2895
3432
|
},
|
|
2896
|
-
(args) => target(
|
|
3433
|
+
(args) => target(str5(args.group), `grant ${str5(args.group)}`)
|
|
2897
3434
|
);
|
|
2898
3435
|
reg(
|
|
2899
3436
|
"features_revoke",
|
|
@@ -2901,7 +3438,7 @@ function registerFeaturesBridge(host, options) {
|
|
|
2901
3438
|
{ subject: { description: "Opaque subject." }, group: { type: "string" }, confirm: { type: "boolean" } },
|
|
2902
3439
|
["subject", "group"],
|
|
2903
3440
|
async (args) => {
|
|
2904
|
-
const groupKey =
|
|
3441
|
+
const groupKey = str5(args.group);
|
|
2905
3442
|
if (!groupKey) return errorResult("group is required.");
|
|
2906
3443
|
const blocked = await guardGrant("features_revoke", args.subject, groupKey, args.confirm === true);
|
|
2907
3444
|
if (blocked) return blocked;
|
|
@@ -2919,7 +3456,7 @@ function registerFeaturesBridge(host, options) {
|
|
|
2919
3456
|
});
|
|
2920
3457
|
return textResult(`Revoked group ${groupKey}`, { subject: args.subject, group: groupKey });
|
|
2921
3458
|
},
|
|
2922
|
-
(args) => target(
|
|
3459
|
+
(args) => target(str5(args.group), `revoke ${str5(args.group)}`)
|
|
2923
3460
|
);
|
|
2924
3461
|
reg(
|
|
2925
3462
|
"features_consume",
|
|
@@ -2928,14 +3465,14 @@ function registerFeaturesBridge(host, options) {
|
|
|
2928
3465
|
["feature", "subject"],
|
|
2929
3466
|
async (args) => {
|
|
2930
3467
|
if (!adapter.tryConsume) return errorResult("Host did not wire usage metering (tryConsume).");
|
|
2931
|
-
const feature =
|
|
2932
|
-
const amount =
|
|
3468
|
+
const feature = str5(args.feature);
|
|
3469
|
+
const amount = num5(args.amount, 1);
|
|
2933
3470
|
const ok = await adapter.tryConsume(feature, args.subject, amount, args.context);
|
|
2934
3471
|
const remaining = await adapter.remaining(feature, args.subject, args.context);
|
|
2935
3472
|
const out = { feature, ok, amount, remaining };
|
|
2936
3473
|
return textResult(JSON.stringify(out), out);
|
|
2937
3474
|
},
|
|
2938
|
-
(args) => target(
|
|
3475
|
+
(args) => target(str5(args.feature), `consume ${str5(args.feature)}`)
|
|
2939
3476
|
);
|
|
2940
3477
|
return {
|
|
2941
3478
|
id: `features:${featuresId}`,
|
|
@@ -3140,11 +3677,11 @@ function attachSseRelay(server, options) {
|
|
|
3140
3677
|
|
|
3141
3678
|
// src/sharing/use-co-browse-session.ts
|
|
3142
3679
|
init_registry();
|
|
3143
|
-
var
|
|
3680
|
+
var DEFAULT_AGENT14 = { id: "agent", name: "Agent", color: "#a855f7" };
|
|
3144
3681
|
var USER = { id: "human", name: "You" };
|
|
3145
3682
|
function useCoBrowseSession(options) {
|
|
3146
3683
|
const { adapter, extraBridges } = options;
|
|
3147
|
-
const agent = { ...
|
|
3684
|
+
const agent = { ...DEFAULT_AGENT14, ...options.agent ?? {} };
|
|
3148
3685
|
const relayBaseUrl = options.relayBaseUrl ?? "/agent-relay";
|
|
3149
3686
|
const serverRef = react.useRef(null);
|
|
3150
3687
|
const relayRef = react.useRef(null);
|
|
@@ -4370,7 +4907,9 @@ exports.registerCatalogBridge = registerCatalogBridge;
|
|
|
4370
4907
|
exports.registerChartsBridge = registerChartsBridge;
|
|
4371
4908
|
exports.registerCodeBridge = registerCodeBridge;
|
|
4372
4909
|
exports.registerFeaturesBridge = registerFeaturesBridge;
|
|
4910
|
+
exports.registerFilesBridge = registerFilesBridge;
|
|
4373
4911
|
exports.registerFormBridge = registerFormBridge;
|
|
4912
|
+
exports.registerMapBridge = registerMapBridge;
|
|
4374
4913
|
exports.registerNavigationBridge = registerNavigationBridge;
|
|
4375
4914
|
exports.registerSceneBridge = registerSceneBridge;
|
|
4376
4915
|
exports.registerScreensBridge = registerScreensBridge;
|