@particle-academy/agent-integrations 0.21.1 → 0.22.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/map.d.cts +62 -0
- package/dist/bridges/map.d.ts +62 -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/index.cjs +385 -57
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/package.json +16 -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,338 @@ 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
|
+
|
|
1958
2285
|
// src/bridges/terminal.ts
|
|
1959
|
-
var
|
|
2286
|
+
var DEFAULT_AGENT9 = { id: "agent", name: "Agent", color: "#a855f7" };
|
|
1960
2287
|
var truncate = (s, n = 60) => s.length > n ? s.slice(0, n) + "\u2026" : s;
|
|
1961
2288
|
function registerTerminalBridge(host, options) {
|
|
1962
|
-
const agent = { ...
|
|
2289
|
+
const agent = { ...DEFAULT_AGENT9, ...options.agent ?? {} };
|
|
1963
2290
|
const pendingMode = options.pendingMode ?? false;
|
|
1964
2291
|
const screenId = options.screenId ?? options.adapter?.screenId;
|
|
1965
2292
|
const disposers = [];
|
|
@@ -2224,10 +2551,10 @@ function registerTerminalBridge(host, options) {
|
|
|
2224
2551
|
}
|
|
2225
2552
|
|
|
2226
2553
|
// src/bridges/navigation.ts
|
|
2227
|
-
var
|
|
2554
|
+
var DEFAULT_AGENT10 = { id: "agent", name: "Agent", color: "#a855f7" };
|
|
2228
2555
|
function registerNavigationBridge(host, options) {
|
|
2229
2556
|
const { adapter } = options;
|
|
2230
|
-
const agent = { ...
|
|
2557
|
+
const agent = { ...DEFAULT_AGENT10, ...options.agent ?? {} };
|
|
2231
2558
|
const pendingMode = options.pendingMode ?? true;
|
|
2232
2559
|
const disposers = [];
|
|
2233
2560
|
ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
|
|
@@ -2432,12 +2759,12 @@ function registerNavigationBridge(host, options) {
|
|
|
2432
2759
|
}
|
|
2433
2760
|
|
|
2434
2761
|
// src/bridges/catalog.ts
|
|
2435
|
-
var
|
|
2436
|
-
var
|
|
2437
|
-
var
|
|
2762
|
+
var DEFAULT_AGENT11 = { id: "agent", name: "Agent", color: "#a855f7" };
|
|
2763
|
+
var str3 = (v, fallback = "") => typeof v === "string" ? v : fallback;
|
|
2764
|
+
var num3 = (v, fallback = 0) => typeof v === "number" && Number.isFinite(v) ? v : fallback;
|
|
2438
2765
|
function registerCatalogBridge(host, options) {
|
|
2439
2766
|
const { adapter } = options;
|
|
2440
|
-
const agent = { ...
|
|
2767
|
+
const agent = { ...DEFAULT_AGENT11, ...options.agent ?? {} };
|
|
2441
2768
|
const pendingMode = options.pendingMode ?? true;
|
|
2442
2769
|
const catalogId = adapter.id ?? "catalog";
|
|
2443
2770
|
const disposers = [];
|
|
@@ -2507,7 +2834,7 @@ function registerCatalogBridge(host, options) {
|
|
|
2507
2834
|
{ id: { type: "string" }, withTrashed: { type: "boolean" } },
|
|
2508
2835
|
["id"],
|
|
2509
2836
|
async (args) => {
|
|
2510
|
-
const id =
|
|
2837
|
+
const id = str3(args.id);
|
|
2511
2838
|
const product = await adapter.products.find(id, { withTrashed: args.withTrashed === true });
|
|
2512
2839
|
if (!product) return errorResult(`No product with id ${id}`);
|
|
2513
2840
|
const prices = await adapter.prices.forProduct(id, { withTrashed: args.withTrashed === true });
|
|
@@ -2523,7 +2850,7 @@ function registerCatalogBridge(host, options) {
|
|
|
2523
2850
|
[],
|
|
2524
2851
|
async (args) => {
|
|
2525
2852
|
const withTrashed = args.withTrashed === true;
|
|
2526
|
-
const prices = args.productId !== void 0 ? await adapter.prices.forProduct(
|
|
2853
|
+
const prices = args.productId !== void 0 ? await adapter.prices.forProduct(str3(args.productId), { withTrashed }) : await adapter.prices.all({ withTrashed });
|
|
2527
2854
|
const list = prices.map((p) => ({
|
|
2528
2855
|
id: p.id,
|
|
2529
2856
|
productId: p.productId,
|
|
@@ -2549,13 +2876,13 @@ function registerCatalogBridge(host, options) {
|
|
|
2549
2876
|
},
|
|
2550
2877
|
["name"],
|
|
2551
2878
|
async (args) => {
|
|
2552
|
-
const name =
|
|
2879
|
+
const name = str3(args.name);
|
|
2553
2880
|
if (!name) return errorResult("name is required.");
|
|
2554
2881
|
const product = await adapter.createProduct({
|
|
2555
2882
|
name,
|
|
2556
|
-
...args.description !== void 0 ? { description:
|
|
2883
|
+
...args.description !== void 0 ? { description: str3(args.description) } : {},
|
|
2557
2884
|
...args.active !== void 0 ? { active: args.active === true } : {},
|
|
2558
|
-
...args.lookupKey !== void 0 ? { lookupKey:
|
|
2885
|
+
...args.lookupKey !== void 0 ? { lookupKey: str3(args.lookupKey) } : {},
|
|
2559
2886
|
...args.metadata && typeof args.metadata === "object" ? { metadata: args.metadata } : {}
|
|
2560
2887
|
});
|
|
2561
2888
|
fancyAutoCommon.pushUndoEntry(agent.id, {
|
|
@@ -2568,7 +2895,7 @@ function registerCatalogBridge(host, options) {
|
|
|
2568
2895
|
});
|
|
2569
2896
|
return textResult(`Created product ${product.id} (${product.name})`, product);
|
|
2570
2897
|
},
|
|
2571
|
-
(args) => target(void 0, `create product ${
|
|
2898
|
+
(args) => target(void 0, `create product ${str3(args.name)}`)
|
|
2572
2899
|
);
|
|
2573
2900
|
reg(
|
|
2574
2901
|
"catalog_create_price",
|
|
@@ -2585,19 +2912,19 @@ function registerCatalogBridge(host, options) {
|
|
|
2585
2912
|
},
|
|
2586
2913
|
["productId", "currency", "unitAmount", "type"],
|
|
2587
2914
|
async (args) => {
|
|
2588
|
-
const productId =
|
|
2915
|
+
const productId = str3(args.productId);
|
|
2589
2916
|
const product = await adapter.products.find(productId);
|
|
2590
2917
|
if (!product) return errorResult(`No product with id ${productId}`);
|
|
2591
|
-
const type =
|
|
2918
|
+
const type = str3(args.type);
|
|
2592
2919
|
if (type !== "recurring" && type !== "one_time") return errorResult("type must be 'recurring' or 'one_time'.");
|
|
2593
2920
|
const price = await adapter.createPrice({
|
|
2594
2921
|
productId,
|
|
2595
|
-
currency:
|
|
2596
|
-
unitAmount:
|
|
2922
|
+
currency: str3(args.currency),
|
|
2923
|
+
unitAmount: num3(args.unitAmount),
|
|
2597
2924
|
type,
|
|
2598
|
-
...args.recurringInterval !== void 0 ? { recurringInterval:
|
|
2599
|
-
...args.nickname !== void 0 ? { nickname:
|
|
2600
|
-
...args.lookupKey !== void 0 ? { lookupKey:
|
|
2925
|
+
...args.recurringInterval !== void 0 ? { recurringInterval: str3(args.recurringInterval) } : {},
|
|
2926
|
+
...args.nickname !== void 0 ? { nickname: str3(args.nickname) } : {},
|
|
2927
|
+
...args.lookupKey !== void 0 ? { lookupKey: str3(args.lookupKey) } : {},
|
|
2601
2928
|
...args.metadata && typeof args.metadata === "object" ? { metadata: args.metadata } : {}
|
|
2602
2929
|
});
|
|
2603
2930
|
fancyAutoCommon.pushUndoEntry(agent.id, {
|
|
@@ -2610,7 +2937,7 @@ function registerCatalogBridge(host, options) {
|
|
|
2610
2937
|
});
|
|
2611
2938
|
return textResult(`Created ${type} price ${price.id} on ${productId}`, price);
|
|
2612
2939
|
},
|
|
2613
|
-
(args) => target(
|
|
2940
|
+
(args) => target(str3(args.productId), `create price on ${str3(args.productId)}`)
|
|
2614
2941
|
);
|
|
2615
2942
|
reg(
|
|
2616
2943
|
"catalog_delete_product",
|
|
@@ -2618,7 +2945,7 @@ function registerCatalogBridge(host, options) {
|
|
|
2618
2945
|
{ id: { type: "string" }, confirm: { type: "boolean" } },
|
|
2619
2946
|
["id"],
|
|
2620
2947
|
async (args) => {
|
|
2621
|
-
const id =
|
|
2948
|
+
const id = str3(args.id);
|
|
2622
2949
|
const product = await adapter.products.find(id, { withTrashed: true });
|
|
2623
2950
|
if (!product) return errorResult(`No product with id ${id}`);
|
|
2624
2951
|
const blocked = await guardDestructive("catalog_delete_product", id, product.name, args.confirm === true);
|
|
@@ -2635,7 +2962,7 @@ function registerCatalogBridge(host, options) {
|
|
|
2635
2962
|
});
|
|
2636
2963
|
return textResult(`Deleted product ${id}`, { id });
|
|
2637
2964
|
},
|
|
2638
|
-
(args) => target(
|
|
2965
|
+
(args) => target(str3(args.id), `delete product ${str3(args.id)}`)
|
|
2639
2966
|
);
|
|
2640
2967
|
reg(
|
|
2641
2968
|
"catalog_delete_price",
|
|
@@ -2643,7 +2970,7 @@ function registerCatalogBridge(host, options) {
|
|
|
2643
2970
|
{ id: { type: "string" }, confirm: { type: "boolean" } },
|
|
2644
2971
|
["id"],
|
|
2645
2972
|
async (args) => {
|
|
2646
|
-
const id =
|
|
2973
|
+
const id = str3(args.id);
|
|
2647
2974
|
const price = await adapter.prices.find(id, { withTrashed: true });
|
|
2648
2975
|
if (!price) return errorResult(`No price with id ${id}`);
|
|
2649
2976
|
const blocked = await guardDestructive("catalog_delete_price", id, id, args.confirm === true);
|
|
@@ -2660,7 +2987,7 @@ function registerCatalogBridge(host, options) {
|
|
|
2660
2987
|
});
|
|
2661
2988
|
return textResult(`Deleted price ${id}`, { id });
|
|
2662
2989
|
},
|
|
2663
|
-
(args) => target(
|
|
2990
|
+
(args) => target(str3(args.id), `delete price ${str3(args.id)}`)
|
|
2664
2991
|
);
|
|
2665
2992
|
reg(
|
|
2666
2993
|
"catalog_sync_product",
|
|
@@ -2669,13 +2996,13 @@ function registerCatalogBridge(host, options) {
|
|
|
2669
2996
|
["id"],
|
|
2670
2997
|
async (args) => {
|
|
2671
2998
|
if (!adapter.syncProductAndPrices) return errorResult("Host did not wire Stripe sync.");
|
|
2672
|
-
const id =
|
|
2999
|
+
const id = str3(args.id);
|
|
2673
3000
|
const product = await adapter.products.find(id);
|
|
2674
3001
|
if (!product) return errorResult(`No product with id ${id}`);
|
|
2675
3002
|
const synced = await adapter.syncProductAndPrices(product);
|
|
2676
3003
|
return textResult(`Synced product ${id} to Stripe (${synced.externalId ?? "no external id"})`, synced);
|
|
2677
3004
|
},
|
|
2678
|
-
(args) => target(
|
|
3005
|
+
(args) => target(str3(args.id), `sync product ${str3(args.id)}`)
|
|
2679
3006
|
);
|
|
2680
3007
|
reg(
|
|
2681
3008
|
"catalog_test_connection",
|
|
@@ -2702,13 +3029,13 @@ function registerCatalogBridge(host, options) {
|
|
|
2702
3029
|
},
|
|
2703
3030
|
["priceId", "successUrl", "cancelUrl"],
|
|
2704
3031
|
async (args) => {
|
|
2705
|
-
const priceId =
|
|
3032
|
+
const priceId = str3(args.priceId);
|
|
2706
3033
|
const price = await adapter.prices.find(priceId);
|
|
2707
3034
|
if (!price) return errorResult(`No price with id ${priceId}`);
|
|
2708
3035
|
const checkoutArgs = {
|
|
2709
|
-
successUrl:
|
|
2710
|
-
cancelUrl:
|
|
2711
|
-
...args.customer !== void 0 ? { customer:
|
|
3036
|
+
successUrl: str3(args.successUrl),
|
|
3037
|
+
cancelUrl: str3(args.cancelUrl),
|
|
3038
|
+
...args.customer !== void 0 ? { customer: str3(args.customer) } : {},
|
|
2712
3039
|
...args.metadata && typeof args.metadata === "object" ? { metadata: args.metadata } : {}
|
|
2713
3040
|
};
|
|
2714
3041
|
let url;
|
|
@@ -2717,11 +3044,11 @@ function registerCatalogBridge(host, options) {
|
|
|
2717
3044
|
url = await adapter.getSubscriptionCheckoutUrl(price, checkoutArgs);
|
|
2718
3045
|
} else {
|
|
2719
3046
|
if (!adapter.getOneTimeCheckoutUrl) return errorResult("Host did not wire one-time checkout.");
|
|
2720
|
-
url = await adapter.getOneTimeCheckoutUrl(price, { ...checkoutArgs, quantity:
|
|
3047
|
+
url = await adapter.getOneTimeCheckoutUrl(price, { ...checkoutArgs, quantity: num3(args.quantity, 1) });
|
|
2721
3048
|
}
|
|
2722
3049
|
return textResult(url || "(no url)", { priceId, type: price.type, url });
|
|
2723
3050
|
},
|
|
2724
|
-
(args) => target(
|
|
3051
|
+
(args) => target(str3(args.priceId), `checkout ${str3(args.priceId)}`)
|
|
2725
3052
|
);
|
|
2726
3053
|
return {
|
|
2727
3054
|
id: `catalog:${catalogId}`,
|
|
@@ -2733,12 +3060,12 @@ function registerCatalogBridge(host, options) {
|
|
|
2733
3060
|
}
|
|
2734
3061
|
|
|
2735
3062
|
// src/bridges/features.ts
|
|
2736
|
-
var
|
|
2737
|
-
var
|
|
2738
|
-
var
|
|
3063
|
+
var DEFAULT_AGENT12 = { id: "agent", name: "Agent", color: "#a855f7" };
|
|
3064
|
+
var str4 = (v, fallback = "") => typeof v === "string" ? v : fallback;
|
|
3065
|
+
var num4 = (v, fallback = 0) => typeof v === "number" && Number.isFinite(v) ? v : fallback;
|
|
2739
3066
|
function registerFeaturesBridge(host, options) {
|
|
2740
3067
|
const { adapter } = options;
|
|
2741
|
-
const agent = { ...
|
|
3068
|
+
const agent = { ...DEFAULT_AGENT12, ...options.agent ?? {} };
|
|
2742
3069
|
const pendingMode = options.pendingMode ?? true;
|
|
2743
3070
|
const featuresId = adapter.id ?? "features";
|
|
2744
3071
|
const disposers = [];
|
|
@@ -2799,7 +3126,7 @@ function registerFeaturesBridge(host, options) {
|
|
|
2799
3126
|
{ feature: { type: "string" }, subject: { description: "Opaque subject." }, context: { description: "Optional context." } },
|
|
2800
3127
|
["feature"],
|
|
2801
3128
|
async (args) => {
|
|
2802
|
-
const feature =
|
|
3129
|
+
const feature = str4(args.feature);
|
|
2803
3130
|
const allowed = await adapter.canAccess(feature, args.subject, args.context);
|
|
2804
3131
|
const remaining = await adapter.remaining(feature, args.subject, args.context);
|
|
2805
3132
|
const out = { feature, allowed, remaining };
|
|
@@ -2814,7 +3141,7 @@ function registerFeaturesBridge(host, options) {
|
|
|
2814
3141
|
["feature"],
|
|
2815
3142
|
async (args) => {
|
|
2816
3143
|
if (!adapter.explain) return errorResult("Host did not wire explain().");
|
|
2817
|
-
const result = await adapter.explain(
|
|
3144
|
+
const result = await adapter.explain(str4(args.feature), args.subject, args.context);
|
|
2818
3145
|
return textResult(JSON.stringify(result, null, 2), result);
|
|
2819
3146
|
},
|
|
2820
3147
|
false
|
|
@@ -2843,15 +3170,15 @@ function registerFeaturesBridge(host, options) {
|
|
|
2843
3170
|
},
|
|
2844
3171
|
["key"],
|
|
2845
3172
|
(args) => {
|
|
2846
|
-
const key =
|
|
3173
|
+
const key = str4(args.key);
|
|
2847
3174
|
if (!key) return errorResult("key is required.");
|
|
2848
3175
|
const existed = adapter.registryKeys().includes(key);
|
|
2849
3176
|
const definition = {
|
|
2850
|
-
...args.name !== void 0 ? { name:
|
|
2851
|
-
...args.description !== void 0 ? { description:
|
|
2852
|
-
...args.type !== void 0 ? { type:
|
|
3177
|
+
...args.name !== void 0 ? { name: str4(args.name) } : {},
|
|
3178
|
+
...args.description !== void 0 ? { description: str4(args.description) } : {},
|
|
3179
|
+
...args.type !== void 0 ? { type: str4(args.type) } : {},
|
|
2853
3180
|
...args.enabled !== void 0 ? { enabled: args.enabled === true } : {},
|
|
2854
|
-
...args.limit !== void 0 ? { limit:
|
|
3181
|
+
...args.limit !== void 0 ? { limit: num4(args.limit) } : {}
|
|
2855
3182
|
};
|
|
2856
3183
|
adapter.registerFeature(key, definition);
|
|
2857
3184
|
fancyAutoCommon.pushUndoEntry(agent.id, {
|
|
@@ -2866,7 +3193,7 @@ function registerFeaturesBridge(host, options) {
|
|
|
2866
3193
|
});
|
|
2867
3194
|
return textResult(`${existed ? "Redefined" : "Defined"} feature ${key} (${definition.type ?? "boolean"})`, { key, definition });
|
|
2868
3195
|
},
|
|
2869
|
-
(args) => target(
|
|
3196
|
+
(args) => target(str4(args.key), `define ${str4(args.key)}`)
|
|
2870
3197
|
);
|
|
2871
3198
|
reg(
|
|
2872
3199
|
"features_grant",
|
|
@@ -2874,7 +3201,7 @@ function registerFeaturesBridge(host, options) {
|
|
|
2874
3201
|
{ subject: { description: "Opaque subject." }, group: { type: "string", description: "Feature group key." }, confirm: { type: "boolean" } },
|
|
2875
3202
|
["subject", "group"],
|
|
2876
3203
|
async (args) => {
|
|
2877
|
-
const groupKey =
|
|
3204
|
+
const groupKey = str4(args.group);
|
|
2878
3205
|
if (!groupKey) return errorResult("group is required.");
|
|
2879
3206
|
const blocked = await guardGrant("features_grant", args.subject, groupKey, args.confirm === true);
|
|
2880
3207
|
if (blocked) return blocked;
|
|
@@ -2893,7 +3220,7 @@ function registerFeaturesBridge(host, options) {
|
|
|
2893
3220
|
});
|
|
2894
3221
|
return textResult(`Granted group ${groupKey}`, { subject: args.subject, group: groupKey });
|
|
2895
3222
|
},
|
|
2896
|
-
(args) => target(
|
|
3223
|
+
(args) => target(str4(args.group), `grant ${str4(args.group)}`)
|
|
2897
3224
|
);
|
|
2898
3225
|
reg(
|
|
2899
3226
|
"features_revoke",
|
|
@@ -2901,7 +3228,7 @@ function registerFeaturesBridge(host, options) {
|
|
|
2901
3228
|
{ subject: { description: "Opaque subject." }, group: { type: "string" }, confirm: { type: "boolean" } },
|
|
2902
3229
|
["subject", "group"],
|
|
2903
3230
|
async (args) => {
|
|
2904
|
-
const groupKey =
|
|
3231
|
+
const groupKey = str4(args.group);
|
|
2905
3232
|
if (!groupKey) return errorResult("group is required.");
|
|
2906
3233
|
const blocked = await guardGrant("features_revoke", args.subject, groupKey, args.confirm === true);
|
|
2907
3234
|
if (blocked) return blocked;
|
|
@@ -2919,7 +3246,7 @@ function registerFeaturesBridge(host, options) {
|
|
|
2919
3246
|
});
|
|
2920
3247
|
return textResult(`Revoked group ${groupKey}`, { subject: args.subject, group: groupKey });
|
|
2921
3248
|
},
|
|
2922
|
-
(args) => target(
|
|
3249
|
+
(args) => target(str4(args.group), `revoke ${str4(args.group)}`)
|
|
2923
3250
|
);
|
|
2924
3251
|
reg(
|
|
2925
3252
|
"features_consume",
|
|
@@ -2928,14 +3255,14 @@ function registerFeaturesBridge(host, options) {
|
|
|
2928
3255
|
["feature", "subject"],
|
|
2929
3256
|
async (args) => {
|
|
2930
3257
|
if (!adapter.tryConsume) return errorResult("Host did not wire usage metering (tryConsume).");
|
|
2931
|
-
const feature =
|
|
2932
|
-
const amount =
|
|
3258
|
+
const feature = str4(args.feature);
|
|
3259
|
+
const amount = num4(args.amount, 1);
|
|
2933
3260
|
const ok = await adapter.tryConsume(feature, args.subject, amount, args.context);
|
|
2934
3261
|
const remaining = await adapter.remaining(feature, args.subject, args.context);
|
|
2935
3262
|
const out = { feature, ok, amount, remaining };
|
|
2936
3263
|
return textResult(JSON.stringify(out), out);
|
|
2937
3264
|
},
|
|
2938
|
-
(args) => target(
|
|
3265
|
+
(args) => target(str4(args.feature), `consume ${str4(args.feature)}`)
|
|
2939
3266
|
);
|
|
2940
3267
|
return {
|
|
2941
3268
|
id: `features:${featuresId}`,
|
|
@@ -3140,11 +3467,11 @@ function attachSseRelay(server, options) {
|
|
|
3140
3467
|
|
|
3141
3468
|
// src/sharing/use-co-browse-session.ts
|
|
3142
3469
|
init_registry();
|
|
3143
|
-
var
|
|
3470
|
+
var DEFAULT_AGENT13 = { id: "agent", name: "Agent", color: "#a855f7" };
|
|
3144
3471
|
var USER = { id: "human", name: "You" };
|
|
3145
3472
|
function useCoBrowseSession(options) {
|
|
3146
3473
|
const { adapter, extraBridges } = options;
|
|
3147
|
-
const agent = { ...
|
|
3474
|
+
const agent = { ...DEFAULT_AGENT13, ...options.agent ?? {} };
|
|
3148
3475
|
const relayBaseUrl = options.relayBaseUrl ?? "/agent-relay";
|
|
3149
3476
|
const serverRef = react.useRef(null);
|
|
3150
3477
|
const relayRef = react.useRef(null);
|
|
@@ -4371,6 +4698,7 @@ exports.registerChartsBridge = registerChartsBridge;
|
|
|
4371
4698
|
exports.registerCodeBridge = registerCodeBridge;
|
|
4372
4699
|
exports.registerFeaturesBridge = registerFeaturesBridge;
|
|
4373
4700
|
exports.registerFormBridge = registerFormBridge;
|
|
4701
|
+
exports.registerMapBridge = registerMapBridge;
|
|
4374
4702
|
exports.registerNavigationBridge = registerNavigationBridge;
|
|
4375
4703
|
exports.registerSceneBridge = registerSceneBridge;
|
|
4376
4704
|
exports.registerScreensBridge = registerScreensBridge;
|