@particle-academy/agent-integrations 0.20.0 → 0.21.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/catalog.d.cts +150 -0
- package/dist/bridges/catalog.d.ts +150 -0
- package/dist/bridges/features.d.cts +108 -0
- package/dist/bridges/features.d.ts +108 -0
- package/dist/bridges-catalog.cjs +428 -0
- package/dist/bridges-catalog.cjs.map +1 -0
- package/dist/bridges-catalog.js +7 -0
- package/dist/bridges-catalog.js.map +1 -0
- package/dist/bridges-features.cjs +341 -0
- package/dist/bridges-features.cjs.map +1 -0
- package/dist/bridges-features.js +7 -0
- package/dist/bridges-features.js.map +1 -0
- package/dist/chunk-267JS64O.js +308 -0
- package/dist/chunk-267JS64O.js.map +1 -0
- package/dist/chunk-XQZGB4FP.js +221 -0
- package/dist/chunk-XQZGB4FP.js.map +1 -0
- package/dist/index.cjs +519 -2
- 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 +31 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/bridges/features.ts"],"names":[],"mappings":"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","file":"chunk-XQZGB4FP.js","sourcesContent":["import { textResult, errorResult } from \"../mcp/server\";\nimport type { ToolHost } from \"../mcp/tool-host\";\nimport type { JsonObject } from \"../mcp/types\";\nimport type { Bridge } from \"./types\";\nimport { wrapToolWithActivity } from \"../presence/wrap-tool-with-activity\";\nimport type { AgentTarget } from \"../presence/types\";\nimport { pushUndoEntry } from \"../undo/undo-stack\";\nimport { ensureUndoToolsRegistered } from \"../undo/undo-tools\";\n\n/**\n * Headless bridge for `@particle-academy/fancy-features` — feature management\n * with NO UI surface. The adapter is the `FeatureManager` (a `FeatureSource`\n * consumer): define features in the registry, check access for a subject,\n * grant/revoke via group assignment, and meter resource usage. Mutations\n * funnel through `wrapToolWithActivity` so presence + undo compose; `grant` /\n * `revoke` are `pendingMode`-gated (they change what a real user can do).\n *\n * The adapter shapes mirror fancy-features' public `FeatureManager` +\n * `FeatureRegistry` + `GroupStore`, defined LOCALLY so the bridge builds with\n * the sibling absent (optional peer). A live `FeatureManager` (plus its\n * `.registry` / `.groupStore`) satisfies this structurally with no import.\n *\n * SUBJECTS over the wire: `Subject` is opaque (`unknown`) in fancy-features.\n * Agents pass a JSON-serializable subject (string id or `{ id, … }` object);\n * the host's stores key on it via their `defaultSubjectKey`.\n */\n\nexport type FeatureGrant = {\n key: string;\n type: \"boolean\" | \"resource\";\n enabled: boolean;\n includedQuantity?: number | null;\n overageLimit?: number | null;\n source?: string;\n config?: Record<string, unknown>;\n};\n\n/** Normalized feature definition (mirror of fancy-features `FeatureDefinition`). */\nexport type FeatureDefinition = {\n key?: string;\n name?: string;\n description?: string;\n type?: \"boolean\" | \"resource\";\n enabled?: boolean;\n limit?: number;\n [k: string]: unknown;\n};\n\n/**\n * Adapter = the `FeatureManager` + its registry + group store. The bridge only\n * needs these members; a real manager exposes them directly.\n */\nexport type FeaturesBridgeAdapter = {\n /** Stable id for this feature manager instance. */\n id?: string;\n title?: string;\n screenId?: string;\n\n // ── Access checks (FeatureManager) ──\n /** Can the subject access the feature now? `manager.canAccess`. */\n canAccess(feature: string, subject?: unknown, context?: unknown): boolean | Promise<boolean>;\n /** Remaining quota for a resource feature (null = unlimited / n-a). `manager.remaining`. */\n remaining(feature: string, subject?: unknown, context?: unknown): number | null | Promise<number | null>;\n /** All enabled feature keys for the subject. `manager.enabled`. */\n enabled(subject?: unknown, context?: unknown): string[] | Promise<string[]>;\n /** Trace a feature's resolution to an AccessResult. `manager.explain`. */\n explain?(feature: string, subject?: unknown, context?: unknown): Promise<unknown> | unknown;\n\n // ── Registry (define) ──\n /** Register a programmatic feature. `manager.registerFeature` / `manager.registry.register`. */\n registerFeature(key: string, definition: FeatureDefinition): void;\n /** Registered feature keys. `manager.registry.keys`. */\n registryKeys(): string[];\n /** Resolve a registered definition (or null). `manager.registry.definition`. */\n definition?(key: string): FeatureDefinition | null | Promise<FeatureDefinition | null>;\n\n // ── Group store (grant / revoke) ──\n /** Assign a subject to a feature group (the grant primitive). `manager.groupStore.assign`. */\n assignGroup(subject: unknown, groupKey: string): void | Promise<void>;\n /** Detach a subject from a group (the revoke primitive). `manager.groupStore.detach`. */\n detachGroup(subject: unknown, groupKey: string): void | Promise<void>;\n /** Group keys assigned to a subject. `manager.groupStore.list`. */\n listGroups(subject: unknown): string[] | Promise<string[]>;\n\n // ── Usage / metering (resource features) ──\n /** Current usage for a resource feature. `manager.usageFor`. Optional. */\n usageFor?(feature: string, subject: unknown): number | Promise<number>;\n /** Atomic check-and-increment quota. `manager.tryConsume`. Optional. */\n tryConsume?(feature: string, subject: unknown, amount?: number, context?: unknown): boolean | Promise<boolean>;\n};\n\nexport type FeaturesBridgeOptions = {\n adapter: FeaturesBridgeAdapter;\n agent?: { id: string; name?: string; color?: string };\n /**\n * Trust-but-verify. When on (default), `features_grant` / `features_revoke`\n * (they change a real subject's entitlements) require `confirm:true` OR a\n * host `confirm` hook. Checks + define + usage are unaffected.\n */\n pendingMode?: boolean;\n confirm?: (req: { action: string; subject: unknown; groupKey: string }) => Promise<boolean> | boolean;\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\n\nconst str = (v: unknown, fallback = \"\"): string => (typeof v === \"string\" ? v : fallback);\nconst num = (v: unknown, fallback = 0): number => (typeof v === \"number\" && Number.isFinite(v) ? v : fallback);\n\n/**\n * registerFeaturesBridge — full MCP tool set over a headless feature manager.\n *\n * features_list enabled feature keys for a subject\n * features_check can a subject access a feature? (+ remaining for resources)\n * features_explain trace why a feature is on/off for a subject\n * features_define register a feature definition (boolean / resource)\n * features_grant assign a subject to a group (pendingMode-gated, undoable)\n * features_revoke detach a subject from a group (pendingMode-gated, undoable)\n * features_groups list a subject's assigned groups\n * features_consume meter a resource feature (atomic check-and-increment)\n */\nexport function registerFeaturesBridge(host: ToolHost, options: FeaturesBridgeOptions): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const pendingMode = options.pendingMode ?? true;\n const featuresId = adapter.id ?? \"features\";\n const disposers: Array<() => void> = [];\n\n ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });\n\n const target = (elementId?: string, label?: string): AgentTarget => ({\n kind: \"custom\",\n screenId: adapter.screenId,\n elementId,\n label: label ?? featuresId,\n });\n\n const reg = (\n name: string,\n description: string,\n properties: Record<string, unknown>,\n required: string[],\n handler: (args: JsonObject) => Promise<unknown> | unknown,\n resolveTarget: false | ((args: JsonObject) => AgentTarget),\n ) => {\n const wrapped = async (args: JsonObject) => {\n try {\n return await handler(args);\n } catch (e) {\n return errorResult(e instanceof Error ? e.message : String(e));\n }\n };\n const final = resolveTarget\n ? wrapToolWithActivity(wrapped as never, {\n toolName: name,\n agent,\n kind: \"custom\",\n screenId: adapter.screenId,\n resolveTarget: ({ args }) => resolveTarget(args as JsonObject),\n })\n : wrapped;\n disposers.push(\n host.registerTool(\n { name, description, inputSchema: { type: \"object\", properties: properties as Record<string, never>, required, additionalProperties: false } },\n final as never,\n ),\n );\n };\n\n const guardGrant = async (action: string, subject: unknown, groupKey: string, hasConfirmArg: boolean) => {\n if (!pendingMode) return null;\n if (options.confirm) {\n const ok = await options.confirm({ action, subject, groupKey });\n return ok ? null : errorResult(`Declined: ${action} ${groupKey} (human did not confirm).`);\n }\n if (!hasConfirmArg) {\n return errorResult(`${action} is staged (pendingMode). Re-call with confirm:true to apply, or wire a host confirm hook.`);\n }\n return null;\n };\n\n // ─── Read / check tools ──────────────────────────────────────────────────\n\n reg(\n \"features_list\",\n \"List the feature keys enabled for a subject. Pass `subject` (a string id or object).\",\n { subject: { description: \"Opaque subject — string id or { id, … } object.\" }, context: { description: \"Optional resolution context.\" } },\n [],\n async (args) => {\n const keys = await adapter.enabled(args.subject, args.context);\n return textResult(JSON.stringify(keys, null, 2), { subject: args.subject, enabled: keys });\n },\n false,\n );\n\n reg(\n \"features_check\",\n \"Check whether a subject can access a feature. For resource features also returns the remaining quota.\",\n { feature: { type: \"string\" }, subject: { description: \"Opaque subject.\" }, context: { description: \"Optional context.\" } },\n [\"feature\"],\n async (args) => {\n const feature = str(args.feature);\n const allowed = await adapter.canAccess(feature, args.subject, args.context);\n const remaining = await adapter.remaining(feature, args.subject, args.context);\n const out = { feature, allowed, remaining };\n return textResult(JSON.stringify(out), out);\n },\n false,\n );\n\n reg(\n \"features_explain\",\n \"Trace why a feature is on/off for a subject — returns the AccessResult (source, remaining, limit, used).\",\n { feature: { type: \"string\" }, subject: { description: \"Opaque subject.\" }, context: { description: \"Optional context.\" } },\n [\"feature\"],\n async (args) => {\n if (!adapter.explain) return errorResult(\"Host did not wire explain().\");\n const result = await adapter.explain(str(args.feature), args.subject, args.context);\n return textResult(JSON.stringify(result, null, 2), result as Record<string, unknown>);\n },\n false,\n );\n\n reg(\n \"features_groups\",\n \"List the feature groups a subject is assigned to.\",\n { subject: { description: \"Opaque subject.\" } },\n [\"subject\"],\n async (args) => {\n const groups = await adapter.listGroups(args.subject);\n return textResult(JSON.stringify(groups, null, 2), { subject: args.subject, groups });\n },\n false,\n );\n\n // ─── Define ──────────────────────────────────────────────────────────────\n\n reg(\n \"features_define\",\n \"Register a feature definition. type 'boolean' (on/off) or 'resource' (metered with a `limit`). `enabled` sets the default gate.\",\n {\n key: { type: \"string\" },\n name: { type: \"string\" },\n description: { type: \"string\" },\n type: { type: \"string\", enum: [\"boolean\", \"resource\"] },\n enabled: { type: \"boolean\" },\n limit: { type: \"number\", description: \"Resource quota per period (resource type).\" },\n },\n [\"key\"],\n (args) => {\n const key = str(args.key);\n if (!key) return errorResult(\"key is required.\");\n const existed = adapter.registryKeys().includes(key);\n const definition: FeatureDefinition = {\n ...(args.name !== undefined ? { name: str(args.name) } : {}),\n ...(args.description !== undefined ? { description: str(args.description) } : {}),\n ...(args.type !== undefined ? { type: str(args.type) as \"boolean\" | \"resource\" } : {}),\n ...(args.enabled !== undefined ? { enabled: args.enabled === true } : {}),\n ...(args.limit !== undefined ? { limit: num(args.limit) } : {}),\n };\n adapter.registerFeature(key, definition);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: featuresId,\n action: \"features_define\",\n // Registry has no unregister; undo re-registers the prior definition when we had one.\n label: existed ? `Redefined feature ${key}` : `Defined feature ${key}`,\n undo: () => {},\n redo: () => adapter.registerFeature(key, definition),\n });\n return textResult(`${existed ? \"Redefined\" : \"Defined\"} feature ${key} (${definition.type ?? \"boolean\"})`, { key, definition });\n },\n (args) => target(str(args.key), `define ${str(args.key)}`),\n );\n\n // ─── Grant / revoke (pendingMode-gated) ──────────────────────────────────\n\n reg(\n \"features_grant\",\n \"Grant a subject access by assigning it to a feature group. Staged in pendingMode — pass confirm:true or wire a host confirm hook.\",\n { subject: { description: \"Opaque subject.\" }, group: { type: \"string\", description: \"Feature group key.\" }, confirm: { type: \"boolean\" } },\n [\"subject\", \"group\"],\n async (args) => {\n const groupKey = str(args.group);\n if (!groupKey) return errorResult(\"group is required.\");\n const blocked = await guardGrant(\"features_grant\", args.subject, groupKey, args.confirm === true);\n if (blocked) return blocked;\n const already = (await adapter.listGroups(args.subject)).includes(groupKey);\n await adapter.assignGroup(args.subject, groupKey);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: featuresId,\n action: \"features_grant\",\n label: `Granted group ${groupKey}`,\n // Only reverse if WE added it (idempotent assign — don't revoke a pre-existing grant).\n undo: () => { if (!already) void adapter.detachGroup(args.subject, groupKey); },\n redo: () => void adapter.assignGroup(args.subject, groupKey),\n });\n return textResult(`Granted group ${groupKey}`, { subject: args.subject, group: groupKey });\n },\n (args) => target(str(args.group), `grant ${str(args.group)}`),\n );\n\n reg(\n \"features_revoke\",\n \"Revoke access by detaching a subject from a feature group. Staged in pendingMode — pass confirm:true or wire a host confirm hook.\",\n { subject: { description: \"Opaque subject.\" }, group: { type: \"string\" }, confirm: { type: \"boolean\" } },\n [\"subject\", \"group\"],\n async (args) => {\n const groupKey = str(args.group);\n if (!groupKey) return errorResult(\"group is required.\");\n const blocked = await guardGrant(\"features_revoke\", args.subject, groupKey, args.confirm === true);\n if (blocked) return blocked;\n const had = (await adapter.listGroups(args.subject)).includes(groupKey);\n await adapter.detachGroup(args.subject, groupKey);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: featuresId,\n action: \"features_revoke\",\n label: `Revoked group ${groupKey}`,\n undo: () => { if (had) void adapter.assignGroup(args.subject, groupKey); },\n redo: () => void adapter.detachGroup(args.subject, groupKey),\n });\n return textResult(`Revoked group ${groupKey}`, { subject: args.subject, group: groupKey });\n },\n (args) => target(str(args.group), `revoke ${str(args.group)}`),\n );\n\n // ─── Usage / metering ────────────────────────────────────────────────────\n\n reg(\n \"features_consume\",\n \"Meter a resource feature: atomic check-and-increment. Returns ok:false if the quota would be exceeded (nothing recorded).\",\n { feature: { type: \"string\" }, subject: { description: \"Opaque subject.\" }, amount: { type: \"number\", description: \"Units to consume. Default 1.\" }, context: { description: \"Optional context.\" } },\n [\"feature\", \"subject\"],\n async (args) => {\n if (!adapter.tryConsume) return errorResult(\"Host did not wire usage metering (tryConsume).\");\n const feature = str(args.feature);\n const amount = num(args.amount, 1);\n const ok = await adapter.tryConsume(feature, args.subject, amount, args.context);\n const remaining = await adapter.remaining(feature, args.subject, args.context);\n const out = { feature, ok, amount, remaining };\n return textResult(JSON.stringify(out), out);\n },\n (args) => target(str(args.feature), `consume ${str(args.feature)}`),\n );\n\n return {\n id: `features:${featuresId}`,\n title: adapter.title ?? \"Features\",\n dispose: () => {\n for (const d of disposers.splice(0)) d();\n },\n };\n}\n"]}
|
package/dist/index.cjs
CHANGED
|
@@ -2431,6 +2431,521 @@ function registerNavigationBridge(host, options) {
|
|
|
2431
2431
|
};
|
|
2432
2432
|
}
|
|
2433
2433
|
|
|
2434
|
+
// src/bridges/catalog.ts
|
|
2435
|
+
var DEFAULT_AGENT10 = { id: "agent", name: "Agent", color: "#a855f7" };
|
|
2436
|
+
var str2 = (v, fallback = "") => typeof v === "string" ? v : fallback;
|
|
2437
|
+
var num2 = (v, fallback = 0) => typeof v === "number" && Number.isFinite(v) ? v : fallback;
|
|
2438
|
+
function registerCatalogBridge(host, options) {
|
|
2439
|
+
const { adapter } = options;
|
|
2440
|
+
const agent = { ...DEFAULT_AGENT10, ...options.agent ?? {} };
|
|
2441
|
+
const pendingMode = options.pendingMode ?? true;
|
|
2442
|
+
const catalogId = adapter.id ?? "catalog";
|
|
2443
|
+
const disposers = [];
|
|
2444
|
+
ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
|
|
2445
|
+
const target = (elementId, label) => ({
|
|
2446
|
+
kind: "custom",
|
|
2447
|
+
screenId: adapter.screenId,
|
|
2448
|
+
elementId,
|
|
2449
|
+
label: label ?? catalogId
|
|
2450
|
+
});
|
|
2451
|
+
const reg = (name, description, properties, required, handler, resolveTarget) => {
|
|
2452
|
+
const wrapped = async (args) => {
|
|
2453
|
+
try {
|
|
2454
|
+
return await handler(args);
|
|
2455
|
+
} catch (e) {
|
|
2456
|
+
return errorResult(e instanceof Error ? e.message : String(e));
|
|
2457
|
+
}
|
|
2458
|
+
};
|
|
2459
|
+
const final = resolveTarget ? wrapToolWithActivity(wrapped, {
|
|
2460
|
+
toolName: name,
|
|
2461
|
+
agent,
|
|
2462
|
+
kind: "custom",
|
|
2463
|
+
screenId: adapter.screenId,
|
|
2464
|
+
resolveTarget: ({ args }) => resolveTarget(args)
|
|
2465
|
+
}) : wrapped;
|
|
2466
|
+
disposers.push(
|
|
2467
|
+
host.registerTool(
|
|
2468
|
+
{ name, description, inputSchema: { type: "object", properties, required, additionalProperties: false } },
|
|
2469
|
+
final
|
|
2470
|
+
)
|
|
2471
|
+
);
|
|
2472
|
+
};
|
|
2473
|
+
const guardDestructive = async (action, id, label, hasConfirmArg) => {
|
|
2474
|
+
if (!pendingMode) return null;
|
|
2475
|
+
if (options.confirm) {
|
|
2476
|
+
const ok = await options.confirm({ action, id, label });
|
|
2477
|
+
return ok ? null : errorResult(`Declined: ${action} ${id} (human did not confirm).`);
|
|
2478
|
+
}
|
|
2479
|
+
if (!hasConfirmArg) {
|
|
2480
|
+
return errorResult(`${action} is staged (pendingMode). Re-call with confirm:true to apply, or wire a host confirm hook.`);
|
|
2481
|
+
}
|
|
2482
|
+
return null;
|
|
2483
|
+
};
|
|
2484
|
+
reg(
|
|
2485
|
+
"catalog_list_products",
|
|
2486
|
+
"List products: { id, name, active, lookupKey, priceCount }. Pass withTrashed:true to include soft-deleted.",
|
|
2487
|
+
{ withTrashed: { type: "boolean" } },
|
|
2488
|
+
[],
|
|
2489
|
+
async (args) => {
|
|
2490
|
+
const products = await adapter.products.all({ withTrashed: args.withTrashed === true });
|
|
2491
|
+
const list = await Promise.all(
|
|
2492
|
+
products.map(async (p) => ({
|
|
2493
|
+
id: p.id,
|
|
2494
|
+
name: p.name,
|
|
2495
|
+
active: p.active ?? true,
|
|
2496
|
+
lookupKey: p.lookupKey ?? null,
|
|
2497
|
+
priceCount: (await adapter.prices.forProduct(p.id)).length
|
|
2498
|
+
}))
|
|
2499
|
+
);
|
|
2500
|
+
return textResult(JSON.stringify(list, null, 2), list);
|
|
2501
|
+
},
|
|
2502
|
+
false
|
|
2503
|
+
);
|
|
2504
|
+
reg(
|
|
2505
|
+
"catalog_get_product",
|
|
2506
|
+
"Read a product's full JSON plus its prices.",
|
|
2507
|
+
{ id: { type: "string" }, withTrashed: { type: "boolean" } },
|
|
2508
|
+
["id"],
|
|
2509
|
+
async (args) => {
|
|
2510
|
+
const id = str2(args.id);
|
|
2511
|
+
const product = await adapter.products.find(id, { withTrashed: args.withTrashed === true });
|
|
2512
|
+
if (!product) return errorResult(`No product with id ${id}`);
|
|
2513
|
+
const prices = await adapter.prices.forProduct(id, { withTrashed: args.withTrashed === true });
|
|
2514
|
+
const out = { product, prices };
|
|
2515
|
+
return textResult(JSON.stringify(out, null, 2), out);
|
|
2516
|
+
},
|
|
2517
|
+
false
|
|
2518
|
+
);
|
|
2519
|
+
reg(
|
|
2520
|
+
"catalog_list_prices",
|
|
2521
|
+
"List prices for a product (pass productId), or every price (omit it).",
|
|
2522
|
+
{ productId: { type: "string" }, withTrashed: { type: "boolean" } },
|
|
2523
|
+
[],
|
|
2524
|
+
async (args) => {
|
|
2525
|
+
const withTrashed = args.withTrashed === true;
|
|
2526
|
+
const prices = args.productId !== void 0 ? await adapter.prices.forProduct(str2(args.productId), { withTrashed }) : await adapter.prices.all({ withTrashed });
|
|
2527
|
+
const list = prices.map((p) => ({
|
|
2528
|
+
id: p.id,
|
|
2529
|
+
productId: p.productId,
|
|
2530
|
+
currency: p.currency,
|
|
2531
|
+
unitAmount: p.unitAmount,
|
|
2532
|
+
type: p.type,
|
|
2533
|
+
active: p.active ?? true,
|
|
2534
|
+
externalId: p.externalId ?? null
|
|
2535
|
+
}));
|
|
2536
|
+
return textResult(JSON.stringify(list, null, 2), list);
|
|
2537
|
+
},
|
|
2538
|
+
false
|
|
2539
|
+
);
|
|
2540
|
+
reg(
|
|
2541
|
+
"catalog_create_product",
|
|
2542
|
+
"Create a product. `name` is required; id (ULID) is auto-assigned. Returns the created product.",
|
|
2543
|
+
{
|
|
2544
|
+
name: { type: "string" },
|
|
2545
|
+
description: { type: "string" },
|
|
2546
|
+
active: { type: "boolean" },
|
|
2547
|
+
lookupKey: { type: "string" },
|
|
2548
|
+
metadata: { type: "object" }
|
|
2549
|
+
},
|
|
2550
|
+
["name"],
|
|
2551
|
+
async (args) => {
|
|
2552
|
+
const name = str2(args.name);
|
|
2553
|
+
if (!name) return errorResult("name is required.");
|
|
2554
|
+
const product = await adapter.createProduct({
|
|
2555
|
+
name,
|
|
2556
|
+
...args.description !== void 0 ? { description: str2(args.description) } : {},
|
|
2557
|
+
...args.active !== void 0 ? { active: args.active === true } : {},
|
|
2558
|
+
...args.lookupKey !== void 0 ? { lookupKey: str2(args.lookupKey) } : {},
|
|
2559
|
+
...args.metadata && typeof args.metadata === "object" ? { metadata: args.metadata } : {}
|
|
2560
|
+
});
|
|
2561
|
+
fancyAutoCommon.pushUndoEntry(agent.id, {
|
|
2562
|
+
timestamp: Date.now(),
|
|
2563
|
+
bridgeId: catalogId,
|
|
2564
|
+
action: "catalog_create_product",
|
|
2565
|
+
label: `Created product ${product.id} (${product.name})`,
|
|
2566
|
+
undo: () => void adapter.products.remove(product.id),
|
|
2567
|
+
redo: () => void adapter.createProduct({ ...product })
|
|
2568
|
+
});
|
|
2569
|
+
return textResult(`Created product ${product.id} (${product.name})`, product);
|
|
2570
|
+
},
|
|
2571
|
+
(args) => target(void 0, `create product ${str2(args.name)}`)
|
|
2572
|
+
);
|
|
2573
|
+
reg(
|
|
2574
|
+
"catalog_create_price",
|
|
2575
|
+
"Create a price under a product. unitAmount is integer minor units (cents). type is 'recurring' | 'one_time'.",
|
|
2576
|
+
{
|
|
2577
|
+
productId: { type: "string" },
|
|
2578
|
+
currency: { type: "string", description: "ISO-4217, e.g. 'USD'." },
|
|
2579
|
+
unitAmount: { type: "number", description: "Price in cents." },
|
|
2580
|
+
type: { type: "string", enum: ["recurring", "one_time"] },
|
|
2581
|
+
recurringInterval: { type: "string", description: "'month' | 'year' | \u2026 (recurring only)." },
|
|
2582
|
+
nickname: { type: "string" },
|
|
2583
|
+
lookupKey: { type: "string" },
|
|
2584
|
+
metadata: { type: "object" }
|
|
2585
|
+
},
|
|
2586
|
+
["productId", "currency", "unitAmount", "type"],
|
|
2587
|
+
async (args) => {
|
|
2588
|
+
const productId = str2(args.productId);
|
|
2589
|
+
const product = await adapter.products.find(productId);
|
|
2590
|
+
if (!product) return errorResult(`No product with id ${productId}`);
|
|
2591
|
+
const type = str2(args.type);
|
|
2592
|
+
if (type !== "recurring" && type !== "one_time") return errorResult("type must be 'recurring' or 'one_time'.");
|
|
2593
|
+
const price = await adapter.createPrice({
|
|
2594
|
+
productId,
|
|
2595
|
+
currency: str2(args.currency),
|
|
2596
|
+
unitAmount: num2(args.unitAmount),
|
|
2597
|
+
type,
|
|
2598
|
+
...args.recurringInterval !== void 0 ? { recurringInterval: str2(args.recurringInterval) } : {},
|
|
2599
|
+
...args.nickname !== void 0 ? { nickname: str2(args.nickname) } : {},
|
|
2600
|
+
...args.lookupKey !== void 0 ? { lookupKey: str2(args.lookupKey) } : {},
|
|
2601
|
+
...args.metadata && typeof args.metadata === "object" ? { metadata: args.metadata } : {}
|
|
2602
|
+
});
|
|
2603
|
+
fancyAutoCommon.pushUndoEntry(agent.id, {
|
|
2604
|
+
timestamp: Date.now(),
|
|
2605
|
+
bridgeId: catalogId,
|
|
2606
|
+
action: "catalog_create_price",
|
|
2607
|
+
label: `Created price ${price.id} on ${productId}`,
|
|
2608
|
+
undo: () => void adapter.prices.remove(price.id),
|
|
2609
|
+
redo: () => void adapter.createPrice({ ...price })
|
|
2610
|
+
});
|
|
2611
|
+
return textResult(`Created ${type} price ${price.id} on ${productId}`, price);
|
|
2612
|
+
},
|
|
2613
|
+
(args) => target(str2(args.productId), `create price on ${str2(args.productId)}`)
|
|
2614
|
+
);
|
|
2615
|
+
reg(
|
|
2616
|
+
"catalog_delete_product",
|
|
2617
|
+
"Soft-delete a product (preserves financial history). Staged in pendingMode \u2014 pass confirm:true or wire a host confirm hook.",
|
|
2618
|
+
{ id: { type: "string" }, confirm: { type: "boolean" } },
|
|
2619
|
+
["id"],
|
|
2620
|
+
async (args) => {
|
|
2621
|
+
const id = str2(args.id);
|
|
2622
|
+
const product = await adapter.products.find(id, { withTrashed: true });
|
|
2623
|
+
if (!product) return errorResult(`No product with id ${id}`);
|
|
2624
|
+
const blocked = await guardDestructive("catalog_delete_product", id, product.name, args.confirm === true);
|
|
2625
|
+
if (blocked) return blocked;
|
|
2626
|
+
const snapshot = { ...product };
|
|
2627
|
+
await adapter.products.remove(id);
|
|
2628
|
+
fancyAutoCommon.pushUndoEntry(agent.id, {
|
|
2629
|
+
timestamp: Date.now(),
|
|
2630
|
+
bridgeId: catalogId,
|
|
2631
|
+
action: "catalog_delete_product",
|
|
2632
|
+
label: `Deleted product ${id} (${product.name})`,
|
|
2633
|
+
undo: () => void adapter.createProduct({ ...snapshot }),
|
|
2634
|
+
redo: () => void adapter.products.remove(id)
|
|
2635
|
+
});
|
|
2636
|
+
return textResult(`Deleted product ${id}`, { id });
|
|
2637
|
+
},
|
|
2638
|
+
(args) => target(str2(args.id), `delete product ${str2(args.id)}`)
|
|
2639
|
+
);
|
|
2640
|
+
reg(
|
|
2641
|
+
"catalog_delete_price",
|
|
2642
|
+
"Soft-delete a price (mirrors Stripe archiving). Staged in pendingMode \u2014 pass confirm:true or wire a host confirm hook.",
|
|
2643
|
+
{ id: { type: "string" }, confirm: { type: "boolean" } },
|
|
2644
|
+
["id"],
|
|
2645
|
+
async (args) => {
|
|
2646
|
+
const id = str2(args.id);
|
|
2647
|
+
const price = await adapter.prices.find(id, { withTrashed: true });
|
|
2648
|
+
if (!price) return errorResult(`No price with id ${id}`);
|
|
2649
|
+
const blocked = await guardDestructive("catalog_delete_price", id, id, args.confirm === true);
|
|
2650
|
+
if (blocked) return blocked;
|
|
2651
|
+
const snapshot = { ...price };
|
|
2652
|
+
await adapter.prices.remove(id);
|
|
2653
|
+
fancyAutoCommon.pushUndoEntry(agent.id, {
|
|
2654
|
+
timestamp: Date.now(),
|
|
2655
|
+
bridgeId: catalogId,
|
|
2656
|
+
action: "catalog_delete_price",
|
|
2657
|
+
label: `Deleted price ${id}`,
|
|
2658
|
+
undo: () => void adapter.createPrice({ ...snapshot }),
|
|
2659
|
+
redo: () => void adapter.prices.remove(id)
|
|
2660
|
+
});
|
|
2661
|
+
return textResult(`Deleted price ${id}`, { id });
|
|
2662
|
+
},
|
|
2663
|
+
(args) => target(str2(args.id), `delete price ${str2(args.id)}`)
|
|
2664
|
+
);
|
|
2665
|
+
reg(
|
|
2666
|
+
"catalog_sync_product",
|
|
2667
|
+
"Push a product + its prices to Stripe (creates/updates the Stripe Product + Prices, stamps external ids).",
|
|
2668
|
+
{ id: { type: "string" } },
|
|
2669
|
+
["id"],
|
|
2670
|
+
async (args) => {
|
|
2671
|
+
if (!adapter.syncProductAndPrices) return errorResult("Host did not wire Stripe sync.");
|
|
2672
|
+
const id = str2(args.id);
|
|
2673
|
+
const product = await adapter.products.find(id);
|
|
2674
|
+
if (!product) return errorResult(`No product with id ${id}`);
|
|
2675
|
+
const synced = await adapter.syncProductAndPrices(product);
|
|
2676
|
+
return textResult(`Synced product ${id} to Stripe (${synced.externalId ?? "no external id"})`, synced);
|
|
2677
|
+
},
|
|
2678
|
+
(args) => target(str2(args.id), `sync product ${str2(args.id)}`)
|
|
2679
|
+
);
|
|
2680
|
+
reg(
|
|
2681
|
+
"catalog_test_connection",
|
|
2682
|
+
"Verify the Stripe connection \u2014 returns { success, message, productCount? }.",
|
|
2683
|
+
{},
|
|
2684
|
+
[],
|
|
2685
|
+
async () => {
|
|
2686
|
+
if (!adapter.testConnection) return errorResult("Host did not wire a Stripe connection test.");
|
|
2687
|
+
const result = await adapter.testConnection();
|
|
2688
|
+
return textResult(JSON.stringify(result, null, 2), result);
|
|
2689
|
+
},
|
|
2690
|
+
false
|
|
2691
|
+
);
|
|
2692
|
+
reg(
|
|
2693
|
+
"catalog_create_checkout",
|
|
2694
|
+
"Build a hosted Stripe Checkout URL for a price. Recurring prices \u2192 subscription; one-time \u2192 payment (pass quantity). Requires the price be synced to Stripe first.",
|
|
2695
|
+
{
|
|
2696
|
+
priceId: { type: "string" },
|
|
2697
|
+
successUrl: { type: "string" },
|
|
2698
|
+
cancelUrl: { type: "string" },
|
|
2699
|
+
customer: { type: "string", description: "Stripe customer id (optional \u2014 Checkout collects one if omitted)." },
|
|
2700
|
+
quantity: { type: "number", description: "One-time checkouts only. Default 1." },
|
|
2701
|
+
metadata: { type: "object" }
|
|
2702
|
+
},
|
|
2703
|
+
["priceId", "successUrl", "cancelUrl"],
|
|
2704
|
+
async (args) => {
|
|
2705
|
+
const priceId = str2(args.priceId);
|
|
2706
|
+
const price = await adapter.prices.find(priceId);
|
|
2707
|
+
if (!price) return errorResult(`No price with id ${priceId}`);
|
|
2708
|
+
const checkoutArgs = {
|
|
2709
|
+
successUrl: str2(args.successUrl),
|
|
2710
|
+
cancelUrl: str2(args.cancelUrl),
|
|
2711
|
+
...args.customer !== void 0 ? { customer: str2(args.customer) } : {},
|
|
2712
|
+
...args.metadata && typeof args.metadata === "object" ? { metadata: args.metadata } : {}
|
|
2713
|
+
};
|
|
2714
|
+
let url;
|
|
2715
|
+
if (price.type === "recurring") {
|
|
2716
|
+
if (!adapter.getSubscriptionCheckoutUrl) return errorResult("Host did not wire subscription checkout.");
|
|
2717
|
+
url = await adapter.getSubscriptionCheckoutUrl(price, checkoutArgs);
|
|
2718
|
+
} else {
|
|
2719
|
+
if (!adapter.getOneTimeCheckoutUrl) return errorResult("Host did not wire one-time checkout.");
|
|
2720
|
+
url = await adapter.getOneTimeCheckoutUrl(price, { ...checkoutArgs, quantity: num2(args.quantity, 1) });
|
|
2721
|
+
}
|
|
2722
|
+
return textResult(url || "(no url)", { priceId, type: price.type, url });
|
|
2723
|
+
},
|
|
2724
|
+
(args) => target(str2(args.priceId), `checkout ${str2(args.priceId)}`)
|
|
2725
|
+
);
|
|
2726
|
+
return {
|
|
2727
|
+
id: `catalog:${catalogId}`,
|
|
2728
|
+
title: adapter.title ?? "Catalog",
|
|
2729
|
+
dispose: () => {
|
|
2730
|
+
for (const d of disposers.splice(0)) d();
|
|
2731
|
+
}
|
|
2732
|
+
};
|
|
2733
|
+
}
|
|
2734
|
+
|
|
2735
|
+
// src/bridges/features.ts
|
|
2736
|
+
var DEFAULT_AGENT11 = { id: "agent", name: "Agent", color: "#a855f7" };
|
|
2737
|
+
var str3 = (v, fallback = "") => typeof v === "string" ? v : fallback;
|
|
2738
|
+
var num3 = (v, fallback = 0) => typeof v === "number" && Number.isFinite(v) ? v : fallback;
|
|
2739
|
+
function registerFeaturesBridge(host, options) {
|
|
2740
|
+
const { adapter } = options;
|
|
2741
|
+
const agent = { ...DEFAULT_AGENT11, ...options.agent ?? {} };
|
|
2742
|
+
const pendingMode = options.pendingMode ?? true;
|
|
2743
|
+
const featuresId = adapter.id ?? "features";
|
|
2744
|
+
const disposers = [];
|
|
2745
|
+
ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
|
|
2746
|
+
const target = (elementId, label) => ({
|
|
2747
|
+
kind: "custom",
|
|
2748
|
+
screenId: adapter.screenId,
|
|
2749
|
+
elementId,
|
|
2750
|
+
label: label ?? featuresId
|
|
2751
|
+
});
|
|
2752
|
+
const reg = (name, description, properties, required, handler, resolveTarget) => {
|
|
2753
|
+
const wrapped = async (args) => {
|
|
2754
|
+
try {
|
|
2755
|
+
return await handler(args);
|
|
2756
|
+
} catch (e) {
|
|
2757
|
+
return errorResult(e instanceof Error ? e.message : String(e));
|
|
2758
|
+
}
|
|
2759
|
+
};
|
|
2760
|
+
const final = resolveTarget ? wrapToolWithActivity(wrapped, {
|
|
2761
|
+
toolName: name,
|
|
2762
|
+
agent,
|
|
2763
|
+
kind: "custom",
|
|
2764
|
+
screenId: adapter.screenId,
|
|
2765
|
+
resolveTarget: ({ args }) => resolveTarget(args)
|
|
2766
|
+
}) : wrapped;
|
|
2767
|
+
disposers.push(
|
|
2768
|
+
host.registerTool(
|
|
2769
|
+
{ name, description, inputSchema: { type: "object", properties, required, additionalProperties: false } },
|
|
2770
|
+
final
|
|
2771
|
+
)
|
|
2772
|
+
);
|
|
2773
|
+
};
|
|
2774
|
+
const guardGrant = async (action, subject, groupKey, hasConfirmArg) => {
|
|
2775
|
+
if (!pendingMode) return null;
|
|
2776
|
+
if (options.confirm) {
|
|
2777
|
+
const ok = await options.confirm({ action, subject, groupKey });
|
|
2778
|
+
return ok ? null : errorResult(`Declined: ${action} ${groupKey} (human did not confirm).`);
|
|
2779
|
+
}
|
|
2780
|
+
if (!hasConfirmArg) {
|
|
2781
|
+
return errorResult(`${action} is staged (pendingMode). Re-call with confirm:true to apply, or wire a host confirm hook.`);
|
|
2782
|
+
}
|
|
2783
|
+
return null;
|
|
2784
|
+
};
|
|
2785
|
+
reg(
|
|
2786
|
+
"features_list",
|
|
2787
|
+
"List the feature keys enabled for a subject. Pass `subject` (a string id or object).",
|
|
2788
|
+
{ subject: { description: "Opaque subject \u2014 string id or { id, \u2026 } object." }, context: { description: "Optional resolution context." } },
|
|
2789
|
+
[],
|
|
2790
|
+
async (args) => {
|
|
2791
|
+
const keys = await adapter.enabled(args.subject, args.context);
|
|
2792
|
+
return textResult(JSON.stringify(keys, null, 2), { subject: args.subject, enabled: keys });
|
|
2793
|
+
},
|
|
2794
|
+
false
|
|
2795
|
+
);
|
|
2796
|
+
reg(
|
|
2797
|
+
"features_check",
|
|
2798
|
+
"Check whether a subject can access a feature. For resource features also returns the remaining quota.",
|
|
2799
|
+
{ feature: { type: "string" }, subject: { description: "Opaque subject." }, context: { description: "Optional context." } },
|
|
2800
|
+
["feature"],
|
|
2801
|
+
async (args) => {
|
|
2802
|
+
const feature = str3(args.feature);
|
|
2803
|
+
const allowed = await adapter.canAccess(feature, args.subject, args.context);
|
|
2804
|
+
const remaining = await adapter.remaining(feature, args.subject, args.context);
|
|
2805
|
+
const out = { feature, allowed, remaining };
|
|
2806
|
+
return textResult(JSON.stringify(out), out);
|
|
2807
|
+
},
|
|
2808
|
+
false
|
|
2809
|
+
);
|
|
2810
|
+
reg(
|
|
2811
|
+
"features_explain",
|
|
2812
|
+
"Trace why a feature is on/off for a subject \u2014 returns the AccessResult (source, remaining, limit, used).",
|
|
2813
|
+
{ feature: { type: "string" }, subject: { description: "Opaque subject." }, context: { description: "Optional context." } },
|
|
2814
|
+
["feature"],
|
|
2815
|
+
async (args) => {
|
|
2816
|
+
if (!adapter.explain) return errorResult("Host did not wire explain().");
|
|
2817
|
+
const result = await adapter.explain(str3(args.feature), args.subject, args.context);
|
|
2818
|
+
return textResult(JSON.stringify(result, null, 2), result);
|
|
2819
|
+
},
|
|
2820
|
+
false
|
|
2821
|
+
);
|
|
2822
|
+
reg(
|
|
2823
|
+
"features_groups",
|
|
2824
|
+
"List the feature groups a subject is assigned to.",
|
|
2825
|
+
{ subject: { description: "Opaque subject." } },
|
|
2826
|
+
["subject"],
|
|
2827
|
+
async (args) => {
|
|
2828
|
+
const groups = await adapter.listGroups(args.subject);
|
|
2829
|
+
return textResult(JSON.stringify(groups, null, 2), { subject: args.subject, groups });
|
|
2830
|
+
},
|
|
2831
|
+
false
|
|
2832
|
+
);
|
|
2833
|
+
reg(
|
|
2834
|
+
"features_define",
|
|
2835
|
+
"Register a feature definition. type 'boolean' (on/off) or 'resource' (metered with a `limit`). `enabled` sets the default gate.",
|
|
2836
|
+
{
|
|
2837
|
+
key: { type: "string" },
|
|
2838
|
+
name: { type: "string" },
|
|
2839
|
+
description: { type: "string" },
|
|
2840
|
+
type: { type: "string", enum: ["boolean", "resource"] },
|
|
2841
|
+
enabled: { type: "boolean" },
|
|
2842
|
+
limit: { type: "number", description: "Resource quota per period (resource type)." }
|
|
2843
|
+
},
|
|
2844
|
+
["key"],
|
|
2845
|
+
(args) => {
|
|
2846
|
+
const key = str3(args.key);
|
|
2847
|
+
if (!key) return errorResult("key is required.");
|
|
2848
|
+
const existed = adapter.registryKeys().includes(key);
|
|
2849
|
+
const definition = {
|
|
2850
|
+
...args.name !== void 0 ? { name: str3(args.name) } : {},
|
|
2851
|
+
...args.description !== void 0 ? { description: str3(args.description) } : {},
|
|
2852
|
+
...args.type !== void 0 ? { type: str3(args.type) } : {},
|
|
2853
|
+
...args.enabled !== void 0 ? { enabled: args.enabled === true } : {},
|
|
2854
|
+
...args.limit !== void 0 ? { limit: num3(args.limit) } : {}
|
|
2855
|
+
};
|
|
2856
|
+
adapter.registerFeature(key, definition);
|
|
2857
|
+
fancyAutoCommon.pushUndoEntry(agent.id, {
|
|
2858
|
+
timestamp: Date.now(),
|
|
2859
|
+
bridgeId: featuresId,
|
|
2860
|
+
action: "features_define",
|
|
2861
|
+
// Registry has no unregister; undo re-registers the prior definition when we had one.
|
|
2862
|
+
label: existed ? `Redefined feature ${key}` : `Defined feature ${key}`,
|
|
2863
|
+
undo: () => {
|
|
2864
|
+
},
|
|
2865
|
+
redo: () => adapter.registerFeature(key, definition)
|
|
2866
|
+
});
|
|
2867
|
+
return textResult(`${existed ? "Redefined" : "Defined"} feature ${key} (${definition.type ?? "boolean"})`, { key, definition });
|
|
2868
|
+
},
|
|
2869
|
+
(args) => target(str3(args.key), `define ${str3(args.key)}`)
|
|
2870
|
+
);
|
|
2871
|
+
reg(
|
|
2872
|
+
"features_grant",
|
|
2873
|
+
"Grant a subject access by assigning it to a feature group. Staged in pendingMode \u2014 pass confirm:true or wire a host confirm hook.",
|
|
2874
|
+
{ subject: { description: "Opaque subject." }, group: { type: "string", description: "Feature group key." }, confirm: { type: "boolean" } },
|
|
2875
|
+
["subject", "group"],
|
|
2876
|
+
async (args) => {
|
|
2877
|
+
const groupKey = str3(args.group);
|
|
2878
|
+
if (!groupKey) return errorResult("group is required.");
|
|
2879
|
+
const blocked = await guardGrant("features_grant", args.subject, groupKey, args.confirm === true);
|
|
2880
|
+
if (blocked) return blocked;
|
|
2881
|
+
const already = (await adapter.listGroups(args.subject)).includes(groupKey);
|
|
2882
|
+
await adapter.assignGroup(args.subject, groupKey);
|
|
2883
|
+
fancyAutoCommon.pushUndoEntry(agent.id, {
|
|
2884
|
+
timestamp: Date.now(),
|
|
2885
|
+
bridgeId: featuresId,
|
|
2886
|
+
action: "features_grant",
|
|
2887
|
+
label: `Granted group ${groupKey}`,
|
|
2888
|
+
// Only reverse if WE added it (idempotent assign — don't revoke a pre-existing grant).
|
|
2889
|
+
undo: () => {
|
|
2890
|
+
if (!already) void adapter.detachGroup(args.subject, groupKey);
|
|
2891
|
+
},
|
|
2892
|
+
redo: () => void adapter.assignGroup(args.subject, groupKey)
|
|
2893
|
+
});
|
|
2894
|
+
return textResult(`Granted group ${groupKey}`, { subject: args.subject, group: groupKey });
|
|
2895
|
+
},
|
|
2896
|
+
(args) => target(str3(args.group), `grant ${str3(args.group)}`)
|
|
2897
|
+
);
|
|
2898
|
+
reg(
|
|
2899
|
+
"features_revoke",
|
|
2900
|
+
"Revoke access by detaching a subject from a feature group. Staged in pendingMode \u2014 pass confirm:true or wire a host confirm hook.",
|
|
2901
|
+
{ subject: { description: "Opaque subject." }, group: { type: "string" }, confirm: { type: "boolean" } },
|
|
2902
|
+
["subject", "group"],
|
|
2903
|
+
async (args) => {
|
|
2904
|
+
const groupKey = str3(args.group);
|
|
2905
|
+
if (!groupKey) return errorResult("group is required.");
|
|
2906
|
+
const blocked = await guardGrant("features_revoke", args.subject, groupKey, args.confirm === true);
|
|
2907
|
+
if (blocked) return blocked;
|
|
2908
|
+
const had = (await adapter.listGroups(args.subject)).includes(groupKey);
|
|
2909
|
+
await adapter.detachGroup(args.subject, groupKey);
|
|
2910
|
+
fancyAutoCommon.pushUndoEntry(agent.id, {
|
|
2911
|
+
timestamp: Date.now(),
|
|
2912
|
+
bridgeId: featuresId,
|
|
2913
|
+
action: "features_revoke",
|
|
2914
|
+
label: `Revoked group ${groupKey}`,
|
|
2915
|
+
undo: () => {
|
|
2916
|
+
if (had) void adapter.assignGroup(args.subject, groupKey);
|
|
2917
|
+
},
|
|
2918
|
+
redo: () => void adapter.detachGroup(args.subject, groupKey)
|
|
2919
|
+
});
|
|
2920
|
+
return textResult(`Revoked group ${groupKey}`, { subject: args.subject, group: groupKey });
|
|
2921
|
+
},
|
|
2922
|
+
(args) => target(str3(args.group), `revoke ${str3(args.group)}`)
|
|
2923
|
+
);
|
|
2924
|
+
reg(
|
|
2925
|
+
"features_consume",
|
|
2926
|
+
"Meter a resource feature: atomic check-and-increment. Returns ok:false if the quota would be exceeded (nothing recorded).",
|
|
2927
|
+
{ feature: { type: "string" }, subject: { description: "Opaque subject." }, amount: { type: "number", description: "Units to consume. Default 1." }, context: { description: "Optional context." } },
|
|
2928
|
+
["feature", "subject"],
|
|
2929
|
+
async (args) => {
|
|
2930
|
+
if (!adapter.tryConsume) return errorResult("Host did not wire usage metering (tryConsume).");
|
|
2931
|
+
const feature = str3(args.feature);
|
|
2932
|
+
const amount = num3(args.amount, 1);
|
|
2933
|
+
const ok = await adapter.tryConsume(feature, args.subject, amount, args.context);
|
|
2934
|
+
const remaining = await adapter.remaining(feature, args.subject, args.context);
|
|
2935
|
+
const out = { feature, ok, amount, remaining };
|
|
2936
|
+
return textResult(JSON.stringify(out), out);
|
|
2937
|
+
},
|
|
2938
|
+
(args) => target(str3(args.feature), `consume ${str3(args.feature)}`)
|
|
2939
|
+
);
|
|
2940
|
+
return {
|
|
2941
|
+
id: `features:${featuresId}`,
|
|
2942
|
+
title: adapter.title ?? "Features",
|
|
2943
|
+
dispose: () => {
|
|
2944
|
+
for (const d of disposers.splice(0)) d();
|
|
2945
|
+
}
|
|
2946
|
+
};
|
|
2947
|
+
}
|
|
2948
|
+
|
|
2434
2949
|
// src/sharing/token.ts
|
|
2435
2950
|
var TOKEN_BYTES = 24;
|
|
2436
2951
|
function createSessionDescriptor() {
|
|
@@ -2625,11 +3140,11 @@ function attachSseRelay(server, options) {
|
|
|
2625
3140
|
|
|
2626
3141
|
// src/sharing/use-co-browse-session.ts
|
|
2627
3142
|
init_registry();
|
|
2628
|
-
var
|
|
3143
|
+
var DEFAULT_AGENT12 = { id: "agent", name: "Agent", color: "#a855f7" };
|
|
2629
3144
|
var USER = { id: "human", name: "You" };
|
|
2630
3145
|
function useCoBrowseSession(options) {
|
|
2631
3146
|
const { adapter, extraBridges } = options;
|
|
2632
|
-
const agent = { ...
|
|
3147
|
+
const agent = { ...DEFAULT_AGENT12, ...options.agent ?? {} };
|
|
2633
3148
|
const relayBaseUrl = options.relayBaseUrl ?? "/agent-relay";
|
|
2634
3149
|
const serverRef = react.useRef(null);
|
|
2635
3150
|
const relayRef = react.useRef(null);
|
|
@@ -3851,8 +4366,10 @@ exports.ensureUndoToolsRegistered = ensureUndoToolsRegistered;
|
|
|
3851
4366
|
exports.errorResult = errorResult;
|
|
3852
4367
|
exports.mapActivityToHeuristicsEvent = mapActivityToEvent;
|
|
3853
4368
|
exports.readSessionFromUrl = readSessionFromUrl;
|
|
4369
|
+
exports.registerCatalogBridge = registerCatalogBridge;
|
|
3854
4370
|
exports.registerChartsBridge = registerChartsBridge;
|
|
3855
4371
|
exports.registerCodeBridge = registerCodeBridge;
|
|
4372
|
+
exports.registerFeaturesBridge = registerFeaturesBridge;
|
|
3856
4373
|
exports.registerFormBridge = registerFormBridge;
|
|
3857
4374
|
exports.registerNavigationBridge = registerNavigationBridge;
|
|
3858
4375
|
exports.registerSceneBridge = registerSceneBridge;
|