@particle-academy/agent-integrations 0.22.0 → 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/index.cjs CHANGED
@@ -2282,11 +2282,221 @@ function registerMapBridge(host, options) {
2282
2282
  };
2283
2283
  }
2284
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
+
2285
2495
  // src/bridges/terminal.ts
2286
- var DEFAULT_AGENT9 = { id: "agent", name: "Agent", color: "#a855f7" };
2496
+ var DEFAULT_AGENT10 = { id: "agent", name: "Agent", color: "#a855f7" };
2287
2497
  var truncate = (s, n = 60) => s.length > n ? s.slice(0, n) + "\u2026" : s;
2288
2498
  function registerTerminalBridge(host, options) {
2289
- const agent = { ...DEFAULT_AGENT9, ...options.agent ?? {} };
2499
+ const agent = { ...DEFAULT_AGENT10, ...options.agent ?? {} };
2290
2500
  const pendingMode = options.pendingMode ?? false;
2291
2501
  const screenId = options.screenId ?? options.adapter?.screenId;
2292
2502
  const disposers = [];
@@ -2551,10 +2761,10 @@ function registerTerminalBridge(host, options) {
2551
2761
  }
2552
2762
 
2553
2763
  // src/bridges/navigation.ts
2554
- var DEFAULT_AGENT10 = { id: "agent", name: "Agent", color: "#a855f7" };
2764
+ var DEFAULT_AGENT11 = { id: "agent", name: "Agent", color: "#a855f7" };
2555
2765
  function registerNavigationBridge(host, options) {
2556
2766
  const { adapter } = options;
2557
- const agent = { ...DEFAULT_AGENT10, ...options.agent ?? {} };
2767
+ const agent = { ...DEFAULT_AGENT11, ...options.agent ?? {} };
2558
2768
  const pendingMode = options.pendingMode ?? true;
2559
2769
  const disposers = [];
2560
2770
  ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
@@ -2759,12 +2969,12 @@ function registerNavigationBridge(host, options) {
2759
2969
  }
2760
2970
 
2761
2971
  // src/bridges/catalog.ts
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;
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;
2765
2975
  function registerCatalogBridge(host, options) {
2766
2976
  const { adapter } = options;
2767
- const agent = { ...DEFAULT_AGENT11, ...options.agent ?? {} };
2977
+ const agent = { ...DEFAULT_AGENT12, ...options.agent ?? {} };
2768
2978
  const pendingMode = options.pendingMode ?? true;
2769
2979
  const catalogId = adapter.id ?? "catalog";
2770
2980
  const disposers = [];
@@ -2834,7 +3044,7 @@ function registerCatalogBridge(host, options) {
2834
3044
  { id: { type: "string" }, withTrashed: { type: "boolean" } },
2835
3045
  ["id"],
2836
3046
  async (args) => {
2837
- const id = str3(args.id);
3047
+ const id = str4(args.id);
2838
3048
  const product = await adapter.products.find(id, { withTrashed: args.withTrashed === true });
2839
3049
  if (!product) return errorResult(`No product with id ${id}`);
2840
3050
  const prices = await adapter.prices.forProduct(id, { withTrashed: args.withTrashed === true });
@@ -2850,7 +3060,7 @@ function registerCatalogBridge(host, options) {
2850
3060
  [],
2851
3061
  async (args) => {
2852
3062
  const withTrashed = args.withTrashed === true;
2853
- const prices = args.productId !== void 0 ? await adapter.prices.forProduct(str3(args.productId), { withTrashed }) : await adapter.prices.all({ withTrashed });
3063
+ const prices = args.productId !== void 0 ? await adapter.prices.forProduct(str4(args.productId), { withTrashed }) : await adapter.prices.all({ withTrashed });
2854
3064
  const list = prices.map((p) => ({
2855
3065
  id: p.id,
2856
3066
  productId: p.productId,
@@ -2876,13 +3086,13 @@ function registerCatalogBridge(host, options) {
2876
3086
  },
2877
3087
  ["name"],
2878
3088
  async (args) => {
2879
- const name = str3(args.name);
3089
+ const name = str4(args.name);
2880
3090
  if (!name) return errorResult("name is required.");
2881
3091
  const product = await adapter.createProduct({
2882
3092
  name,
2883
- ...args.description !== void 0 ? { description: str3(args.description) } : {},
3093
+ ...args.description !== void 0 ? { description: str4(args.description) } : {},
2884
3094
  ...args.active !== void 0 ? { active: args.active === true } : {},
2885
- ...args.lookupKey !== void 0 ? { lookupKey: str3(args.lookupKey) } : {},
3095
+ ...args.lookupKey !== void 0 ? { lookupKey: str4(args.lookupKey) } : {},
2886
3096
  ...args.metadata && typeof args.metadata === "object" ? { metadata: args.metadata } : {}
2887
3097
  });
2888
3098
  fancyAutoCommon.pushUndoEntry(agent.id, {
@@ -2895,7 +3105,7 @@ function registerCatalogBridge(host, options) {
2895
3105
  });
2896
3106
  return textResult(`Created product ${product.id} (${product.name})`, product);
2897
3107
  },
2898
- (args) => target(void 0, `create product ${str3(args.name)}`)
3108
+ (args) => target(void 0, `create product ${str4(args.name)}`)
2899
3109
  );
2900
3110
  reg(
2901
3111
  "catalog_create_price",
@@ -2912,19 +3122,19 @@ function registerCatalogBridge(host, options) {
2912
3122
  },
2913
3123
  ["productId", "currency", "unitAmount", "type"],
2914
3124
  async (args) => {
2915
- const productId = str3(args.productId);
3125
+ const productId = str4(args.productId);
2916
3126
  const product = await adapter.products.find(productId);
2917
3127
  if (!product) return errorResult(`No product with id ${productId}`);
2918
- const type = str3(args.type);
3128
+ const type = str4(args.type);
2919
3129
  if (type !== "recurring" && type !== "one_time") return errorResult("type must be 'recurring' or 'one_time'.");
2920
3130
  const price = await adapter.createPrice({
2921
3131
  productId,
2922
- currency: str3(args.currency),
2923
- unitAmount: num3(args.unitAmount),
3132
+ currency: str4(args.currency),
3133
+ unitAmount: num4(args.unitAmount),
2924
3134
  type,
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) } : {},
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) } : {},
2928
3138
  ...args.metadata && typeof args.metadata === "object" ? { metadata: args.metadata } : {}
2929
3139
  });
2930
3140
  fancyAutoCommon.pushUndoEntry(agent.id, {
@@ -2937,7 +3147,7 @@ function registerCatalogBridge(host, options) {
2937
3147
  });
2938
3148
  return textResult(`Created ${type} price ${price.id} on ${productId}`, price);
2939
3149
  },
2940
- (args) => target(str3(args.productId), `create price on ${str3(args.productId)}`)
3150
+ (args) => target(str4(args.productId), `create price on ${str4(args.productId)}`)
2941
3151
  );
2942
3152
  reg(
2943
3153
  "catalog_delete_product",
@@ -2945,7 +3155,7 @@ function registerCatalogBridge(host, options) {
2945
3155
  { id: { type: "string" }, confirm: { type: "boolean" } },
2946
3156
  ["id"],
2947
3157
  async (args) => {
2948
- const id = str3(args.id);
3158
+ const id = str4(args.id);
2949
3159
  const product = await adapter.products.find(id, { withTrashed: true });
2950
3160
  if (!product) return errorResult(`No product with id ${id}`);
2951
3161
  const blocked = await guardDestructive("catalog_delete_product", id, product.name, args.confirm === true);
@@ -2962,7 +3172,7 @@ function registerCatalogBridge(host, options) {
2962
3172
  });
2963
3173
  return textResult(`Deleted product ${id}`, { id });
2964
3174
  },
2965
- (args) => target(str3(args.id), `delete product ${str3(args.id)}`)
3175
+ (args) => target(str4(args.id), `delete product ${str4(args.id)}`)
2966
3176
  );
2967
3177
  reg(
2968
3178
  "catalog_delete_price",
@@ -2970,7 +3180,7 @@ function registerCatalogBridge(host, options) {
2970
3180
  { id: { type: "string" }, confirm: { type: "boolean" } },
2971
3181
  ["id"],
2972
3182
  async (args) => {
2973
- const id = str3(args.id);
3183
+ const id = str4(args.id);
2974
3184
  const price = await adapter.prices.find(id, { withTrashed: true });
2975
3185
  if (!price) return errorResult(`No price with id ${id}`);
2976
3186
  const blocked = await guardDestructive("catalog_delete_price", id, id, args.confirm === true);
@@ -2987,7 +3197,7 @@ function registerCatalogBridge(host, options) {
2987
3197
  });
2988
3198
  return textResult(`Deleted price ${id}`, { id });
2989
3199
  },
2990
- (args) => target(str3(args.id), `delete price ${str3(args.id)}`)
3200
+ (args) => target(str4(args.id), `delete price ${str4(args.id)}`)
2991
3201
  );
2992
3202
  reg(
2993
3203
  "catalog_sync_product",
@@ -2996,13 +3206,13 @@ function registerCatalogBridge(host, options) {
2996
3206
  ["id"],
2997
3207
  async (args) => {
2998
3208
  if (!adapter.syncProductAndPrices) return errorResult("Host did not wire Stripe sync.");
2999
- const id = str3(args.id);
3209
+ const id = str4(args.id);
3000
3210
  const product = await adapter.products.find(id);
3001
3211
  if (!product) return errorResult(`No product with id ${id}`);
3002
3212
  const synced = await adapter.syncProductAndPrices(product);
3003
3213
  return textResult(`Synced product ${id} to Stripe (${synced.externalId ?? "no external id"})`, synced);
3004
3214
  },
3005
- (args) => target(str3(args.id), `sync product ${str3(args.id)}`)
3215
+ (args) => target(str4(args.id), `sync product ${str4(args.id)}`)
3006
3216
  );
3007
3217
  reg(
3008
3218
  "catalog_test_connection",
@@ -3029,13 +3239,13 @@ function registerCatalogBridge(host, options) {
3029
3239
  },
3030
3240
  ["priceId", "successUrl", "cancelUrl"],
3031
3241
  async (args) => {
3032
- const priceId = str3(args.priceId);
3242
+ const priceId = str4(args.priceId);
3033
3243
  const price = await adapter.prices.find(priceId);
3034
3244
  if (!price) return errorResult(`No price with id ${priceId}`);
3035
3245
  const checkoutArgs = {
3036
- successUrl: str3(args.successUrl),
3037
- cancelUrl: str3(args.cancelUrl),
3038
- ...args.customer !== void 0 ? { customer: str3(args.customer) } : {},
3246
+ successUrl: str4(args.successUrl),
3247
+ cancelUrl: str4(args.cancelUrl),
3248
+ ...args.customer !== void 0 ? { customer: str4(args.customer) } : {},
3039
3249
  ...args.metadata && typeof args.metadata === "object" ? { metadata: args.metadata } : {}
3040
3250
  };
3041
3251
  let url;
@@ -3044,11 +3254,11 @@ function registerCatalogBridge(host, options) {
3044
3254
  url = await adapter.getSubscriptionCheckoutUrl(price, checkoutArgs);
3045
3255
  } else {
3046
3256
  if (!adapter.getOneTimeCheckoutUrl) return errorResult("Host did not wire one-time checkout.");
3047
- url = await adapter.getOneTimeCheckoutUrl(price, { ...checkoutArgs, quantity: num3(args.quantity, 1) });
3257
+ url = await adapter.getOneTimeCheckoutUrl(price, { ...checkoutArgs, quantity: num4(args.quantity, 1) });
3048
3258
  }
3049
3259
  return textResult(url || "(no url)", { priceId, type: price.type, url });
3050
3260
  },
3051
- (args) => target(str3(args.priceId), `checkout ${str3(args.priceId)}`)
3261
+ (args) => target(str4(args.priceId), `checkout ${str4(args.priceId)}`)
3052
3262
  );
3053
3263
  return {
3054
3264
  id: `catalog:${catalogId}`,
@@ -3060,12 +3270,12 @@ function registerCatalogBridge(host, options) {
3060
3270
  }
3061
3271
 
3062
3272
  // src/bridges/features.ts
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;
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;
3066
3276
  function registerFeaturesBridge(host, options) {
3067
3277
  const { adapter } = options;
3068
- const agent = { ...DEFAULT_AGENT12, ...options.agent ?? {} };
3278
+ const agent = { ...DEFAULT_AGENT13, ...options.agent ?? {} };
3069
3279
  const pendingMode = options.pendingMode ?? true;
3070
3280
  const featuresId = adapter.id ?? "features";
3071
3281
  const disposers = [];
@@ -3126,7 +3336,7 @@ function registerFeaturesBridge(host, options) {
3126
3336
  { feature: { type: "string" }, subject: { description: "Opaque subject." }, context: { description: "Optional context." } },
3127
3337
  ["feature"],
3128
3338
  async (args) => {
3129
- const feature = str4(args.feature);
3339
+ const feature = str5(args.feature);
3130
3340
  const allowed = await adapter.canAccess(feature, args.subject, args.context);
3131
3341
  const remaining = await adapter.remaining(feature, args.subject, args.context);
3132
3342
  const out = { feature, allowed, remaining };
@@ -3141,7 +3351,7 @@ function registerFeaturesBridge(host, options) {
3141
3351
  ["feature"],
3142
3352
  async (args) => {
3143
3353
  if (!adapter.explain) return errorResult("Host did not wire explain().");
3144
- const result = await adapter.explain(str4(args.feature), args.subject, args.context);
3354
+ const result = await adapter.explain(str5(args.feature), args.subject, args.context);
3145
3355
  return textResult(JSON.stringify(result, null, 2), result);
3146
3356
  },
3147
3357
  false
@@ -3170,15 +3380,15 @@ function registerFeaturesBridge(host, options) {
3170
3380
  },
3171
3381
  ["key"],
3172
3382
  (args) => {
3173
- const key = str4(args.key);
3383
+ const key = str5(args.key);
3174
3384
  if (!key) return errorResult("key is required.");
3175
3385
  const existed = adapter.registryKeys().includes(key);
3176
3386
  const definition = {
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) } : {},
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) } : {},
3180
3390
  ...args.enabled !== void 0 ? { enabled: args.enabled === true } : {},
3181
- ...args.limit !== void 0 ? { limit: num4(args.limit) } : {}
3391
+ ...args.limit !== void 0 ? { limit: num5(args.limit) } : {}
3182
3392
  };
3183
3393
  adapter.registerFeature(key, definition);
3184
3394
  fancyAutoCommon.pushUndoEntry(agent.id, {
@@ -3193,7 +3403,7 @@ function registerFeaturesBridge(host, options) {
3193
3403
  });
3194
3404
  return textResult(`${existed ? "Redefined" : "Defined"} feature ${key} (${definition.type ?? "boolean"})`, { key, definition });
3195
3405
  },
3196
- (args) => target(str4(args.key), `define ${str4(args.key)}`)
3406
+ (args) => target(str5(args.key), `define ${str5(args.key)}`)
3197
3407
  );
3198
3408
  reg(
3199
3409
  "features_grant",
@@ -3201,7 +3411,7 @@ function registerFeaturesBridge(host, options) {
3201
3411
  { subject: { description: "Opaque subject." }, group: { type: "string", description: "Feature group key." }, confirm: { type: "boolean" } },
3202
3412
  ["subject", "group"],
3203
3413
  async (args) => {
3204
- const groupKey = str4(args.group);
3414
+ const groupKey = str5(args.group);
3205
3415
  if (!groupKey) return errorResult("group is required.");
3206
3416
  const blocked = await guardGrant("features_grant", args.subject, groupKey, args.confirm === true);
3207
3417
  if (blocked) return blocked;
@@ -3220,7 +3430,7 @@ function registerFeaturesBridge(host, options) {
3220
3430
  });
3221
3431
  return textResult(`Granted group ${groupKey}`, { subject: args.subject, group: groupKey });
3222
3432
  },
3223
- (args) => target(str4(args.group), `grant ${str4(args.group)}`)
3433
+ (args) => target(str5(args.group), `grant ${str5(args.group)}`)
3224
3434
  );
3225
3435
  reg(
3226
3436
  "features_revoke",
@@ -3228,7 +3438,7 @@ function registerFeaturesBridge(host, options) {
3228
3438
  { subject: { description: "Opaque subject." }, group: { type: "string" }, confirm: { type: "boolean" } },
3229
3439
  ["subject", "group"],
3230
3440
  async (args) => {
3231
- const groupKey = str4(args.group);
3441
+ const groupKey = str5(args.group);
3232
3442
  if (!groupKey) return errorResult("group is required.");
3233
3443
  const blocked = await guardGrant("features_revoke", args.subject, groupKey, args.confirm === true);
3234
3444
  if (blocked) return blocked;
@@ -3246,7 +3456,7 @@ function registerFeaturesBridge(host, options) {
3246
3456
  });
3247
3457
  return textResult(`Revoked group ${groupKey}`, { subject: args.subject, group: groupKey });
3248
3458
  },
3249
- (args) => target(str4(args.group), `revoke ${str4(args.group)}`)
3459
+ (args) => target(str5(args.group), `revoke ${str5(args.group)}`)
3250
3460
  );
3251
3461
  reg(
3252
3462
  "features_consume",
@@ -3255,14 +3465,14 @@ function registerFeaturesBridge(host, options) {
3255
3465
  ["feature", "subject"],
3256
3466
  async (args) => {
3257
3467
  if (!adapter.tryConsume) return errorResult("Host did not wire usage metering (tryConsume).");
3258
- const feature = str4(args.feature);
3259
- const amount = num4(args.amount, 1);
3468
+ const feature = str5(args.feature);
3469
+ const amount = num5(args.amount, 1);
3260
3470
  const ok = await adapter.tryConsume(feature, args.subject, amount, args.context);
3261
3471
  const remaining = await adapter.remaining(feature, args.subject, args.context);
3262
3472
  const out = { feature, ok, amount, remaining };
3263
3473
  return textResult(JSON.stringify(out), out);
3264
3474
  },
3265
- (args) => target(str4(args.feature), `consume ${str4(args.feature)}`)
3475
+ (args) => target(str5(args.feature), `consume ${str5(args.feature)}`)
3266
3476
  );
3267
3477
  return {
3268
3478
  id: `features:${featuresId}`,
@@ -3467,11 +3677,11 @@ function attachSseRelay(server, options) {
3467
3677
 
3468
3678
  // src/sharing/use-co-browse-session.ts
3469
3679
  init_registry();
3470
- var DEFAULT_AGENT13 = { id: "agent", name: "Agent", color: "#a855f7" };
3680
+ var DEFAULT_AGENT14 = { id: "agent", name: "Agent", color: "#a855f7" };
3471
3681
  var USER = { id: "human", name: "You" };
3472
3682
  function useCoBrowseSession(options) {
3473
3683
  const { adapter, extraBridges } = options;
3474
- const agent = { ...DEFAULT_AGENT13, ...options.agent ?? {} };
3684
+ const agent = { ...DEFAULT_AGENT14, ...options.agent ?? {} };
3475
3685
  const relayBaseUrl = options.relayBaseUrl ?? "/agent-relay";
3476
3686
  const serverRef = react.useRef(null);
3477
3687
  const relayRef = react.useRef(null);
@@ -4697,6 +4907,7 @@ exports.registerCatalogBridge = registerCatalogBridge;
4697
4907
  exports.registerChartsBridge = registerChartsBridge;
4698
4908
  exports.registerCodeBridge = registerCodeBridge;
4699
4909
  exports.registerFeaturesBridge = registerFeaturesBridge;
4910
+ exports.registerFilesBridge = registerFilesBridge;
4700
4911
  exports.registerFormBridge = registerFormBridge;
4701
4912
  exports.registerMapBridge = registerMapBridge;
4702
4913
  exports.registerNavigationBridge = registerNavigationBridge;