@particle-academy/agent-integrations 0.20.0 → 0.21.1
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-54QEFRMS.js → chunk-5HNTNIWY.js} +3 -3
- package/dist/{chunk-54QEFRMS.js.map → chunk-5HNTNIWY.js.map} +1 -1
- package/dist/chunk-XQZGB4FP.js +221 -0
- package/dist/chunk-XQZGB4FP.js.map +1 -0
- package/dist/connectors.cjs +1 -1
- package/dist/connectors.cjs.map +1 -1
- package/dist/connectors.js +1 -1
- package/dist/index.cjs +520 -3
- 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,150 @@
|
|
|
1
|
+
import { T as ToolHost } from '../tool-host-BQuUygLF.cjs';
|
|
2
|
+
import { B as Bridge } from '../types-CCSBGW9T.cjs';
|
|
3
|
+
import '../types-aOQLTW0E.cjs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Headless bridge for `@particle-academy/fancy-catalog` — a Stripe catalog with
|
|
7
|
+
* NO UI surface. The adapter exposes the catalog's STORES + operations (not UI
|
|
8
|
+
* getters/setters), and the tools are CRUD over products / prices + checkout +
|
|
9
|
+
* Stripe sync. Mutations still funnel through `wrapToolWithActivity` so presence
|
|
10
|
+
* + undo compose, and the destructive delete is `pendingMode`-gated.
|
|
11
|
+
*
|
|
12
|
+
* The adapter shapes below are STRUCTURAL mirrors of fancy-catalog's public
|
|
13
|
+
* `Catalog` + store interfaces, defined LOCALLY so this bridge builds with the
|
|
14
|
+
* sibling package absent (it's an optional peer). A real `Catalog` instance is
|
|
15
|
+
* assignable to `CatalogBridgeAdapter` with no import — TypeScript is structural.
|
|
16
|
+
*/
|
|
17
|
+
/** Minimal product shape crossing the MCP wire (mirror of fancy-catalog `Product`). */
|
|
18
|
+
type CatalogProduct = {
|
|
19
|
+
id: string;
|
|
20
|
+
name: string;
|
|
21
|
+
description?: string | null;
|
|
22
|
+
active?: boolean;
|
|
23
|
+
lookupKey?: string | null;
|
|
24
|
+
externalId?: string | null;
|
|
25
|
+
metadata?: Record<string, unknown> | null;
|
|
26
|
+
[k: string]: unknown;
|
|
27
|
+
};
|
|
28
|
+
/** Minimal price shape crossing the MCP wire (mirror of fancy-catalog `Price`). */
|
|
29
|
+
type CatalogPrice = {
|
|
30
|
+
id: string;
|
|
31
|
+
productId: string;
|
|
32
|
+
active?: boolean;
|
|
33
|
+
currency: string;
|
|
34
|
+
unitAmount: number;
|
|
35
|
+
type: "recurring" | "one_time";
|
|
36
|
+
externalId?: string | null;
|
|
37
|
+
[k: string]: unknown;
|
|
38
|
+
};
|
|
39
|
+
/** Common checkout args (mirror of fancy-catalog `CheckoutArgs`). */
|
|
40
|
+
type CatalogCheckoutArgs = {
|
|
41
|
+
customer?: string;
|
|
42
|
+
successUrl: string;
|
|
43
|
+
cancelUrl: string;
|
|
44
|
+
metadata?: Record<string, string>;
|
|
45
|
+
/** One-time checkouts only. */
|
|
46
|
+
quantity?: number;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Adapter = the catalog instance / stores. A live `Catalog` from fancy-catalog
|
|
50
|
+
* satisfies this directly (`catalog.products`, `catalog.createProduct`, …); a
|
|
51
|
+
* host can also hand-roll one over its own persistence.
|
|
52
|
+
*/
|
|
53
|
+
type CatalogBridgeAdapter = {
|
|
54
|
+
/** Stable id for this catalog instance (multiple catalogs ⇒ distinct ids). */
|
|
55
|
+
id?: string;
|
|
56
|
+
/** Display label for logs / presence. */
|
|
57
|
+
title?: string;
|
|
58
|
+
/** Optional fancy-screens screen id (usually unset — this is headless). */
|
|
59
|
+
screenId?: string;
|
|
60
|
+
/** Product store — `catalog.products`. */
|
|
61
|
+
products: {
|
|
62
|
+
find(id: string, opts?: {
|
|
63
|
+
withTrashed?: boolean;
|
|
64
|
+
}): CatalogProduct | null | Promise<CatalogProduct | null>;
|
|
65
|
+
all(opts?: {
|
|
66
|
+
withTrashed?: boolean;
|
|
67
|
+
}): CatalogProduct[] | Promise<CatalogProduct[]>;
|
|
68
|
+
remove(id: string): void | Promise<void>;
|
|
69
|
+
};
|
|
70
|
+
/** Price store — `catalog.prices`. */
|
|
71
|
+
prices: {
|
|
72
|
+
find(id: string, opts?: {
|
|
73
|
+
withTrashed?: boolean;
|
|
74
|
+
}): CatalogPrice | null | Promise<CatalogPrice | null>;
|
|
75
|
+
forProduct(productId: string, opts?: {
|
|
76
|
+
withTrashed?: boolean;
|
|
77
|
+
}): CatalogPrice[] | Promise<CatalogPrice[]>;
|
|
78
|
+
all(opts?: {
|
|
79
|
+
withTrashed?: boolean;
|
|
80
|
+
}): CatalogPrice[] | Promise<CatalogPrice[]>;
|
|
81
|
+
remove(id: string): void | Promise<void>;
|
|
82
|
+
};
|
|
83
|
+
/** Authoring helpers — `catalog.createProduct` / `catalog.createPrice` (ULIDs auto-assigned). */
|
|
84
|
+
createProduct(input: Partial<CatalogProduct> & {
|
|
85
|
+
name: string;
|
|
86
|
+
}): Promise<CatalogProduct> | CatalogProduct;
|
|
87
|
+
createPrice(input: Partial<CatalogPrice> & {
|
|
88
|
+
productId: string;
|
|
89
|
+
currency: string;
|
|
90
|
+
unitAmount: number;
|
|
91
|
+
type: "recurring" | "one_time";
|
|
92
|
+
}): Promise<CatalogPrice> | CatalogPrice;
|
|
93
|
+
/** Stripe sync — `catalog.syncProductAndPrices`. Optional (no-op when absent). */
|
|
94
|
+
syncProductAndPrices?(product: CatalogProduct): Promise<CatalogProduct> | CatalogProduct;
|
|
95
|
+
/** Connection test — `catalog.testConnection`. Optional. */
|
|
96
|
+
testConnection?(): Promise<{
|
|
97
|
+
success: boolean;
|
|
98
|
+
message: string;
|
|
99
|
+
productCount?: number;
|
|
100
|
+
}> | {
|
|
101
|
+
success: boolean;
|
|
102
|
+
message: string;
|
|
103
|
+
productCount?: number;
|
|
104
|
+
};
|
|
105
|
+
/** Hosted Checkout — `catalog.getSubscriptionCheckoutUrl` / `getOneTimeCheckoutUrl`. Optional. */
|
|
106
|
+
getSubscriptionCheckoutUrl?(price: CatalogPrice, args: CatalogCheckoutArgs): Promise<string> | string;
|
|
107
|
+
getOneTimeCheckoutUrl?(price: CatalogPrice, args: CatalogCheckoutArgs): Promise<string> | string;
|
|
108
|
+
};
|
|
109
|
+
type CatalogBridgeOptions = {
|
|
110
|
+
adapter: CatalogBridgeAdapter;
|
|
111
|
+
/** Identity stamped on activity + undo entries. */
|
|
112
|
+
agent?: {
|
|
113
|
+
id: string;
|
|
114
|
+
name?: string;
|
|
115
|
+
color?: string;
|
|
116
|
+
};
|
|
117
|
+
/**
|
|
118
|
+
* Trust-but-verify. When on (default), destructive ops (`catalog_delete_product`,
|
|
119
|
+
* `catalog_delete_price`) route through `adapter`-less staging: they require an
|
|
120
|
+
* explicit `confirm: true` arg OR a host `confirm` callback. Read + create +
|
|
121
|
+
* checkout-url tools are unaffected.
|
|
122
|
+
*/
|
|
123
|
+
pendingMode?: boolean;
|
|
124
|
+
/** Host confirm hook for destructive ops (pendingMode). Resolves true to proceed. */
|
|
125
|
+
confirm?: (req: {
|
|
126
|
+
action: string;
|
|
127
|
+
id: string;
|
|
128
|
+
label: string;
|
|
129
|
+
}) => Promise<boolean> | boolean;
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* registerCatalogBridge — full MCP tool set over a headless Stripe catalog.
|
|
133
|
+
*
|
|
134
|
+
* catalog_list_products list products ({ id, name, active, priceCount })
|
|
135
|
+
* catalog_get_product full product JSON + its prices
|
|
136
|
+
* catalog_create_product create a product (ULID auto-assigned)
|
|
137
|
+
* catalog_delete_product soft-delete a product (pendingMode-gated, undoable*)
|
|
138
|
+
* catalog_list_prices list a product's prices (or all)
|
|
139
|
+
* catalog_create_price create a price under a product
|
|
140
|
+
* catalog_delete_price soft-delete a price (pendingMode-gated)
|
|
141
|
+
* catalog_sync_product push a product + its prices to Stripe
|
|
142
|
+
* catalog_test_connection verify the Stripe connection
|
|
143
|
+
* catalog_create_checkout build a hosted Checkout URL for a price
|
|
144
|
+
*
|
|
145
|
+
* *delete undo is best-effort: stores expose soft-delete (`remove`) but no
|
|
146
|
+
* un-delete, so the undo closure re-creates from the captured snapshot.
|
|
147
|
+
*/
|
|
148
|
+
declare function registerCatalogBridge(host: ToolHost, options: CatalogBridgeOptions): Bridge;
|
|
149
|
+
|
|
150
|
+
export { type CatalogBridgeAdapter, type CatalogBridgeOptions, type CatalogCheckoutArgs, type CatalogPrice, type CatalogProduct, registerCatalogBridge };
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { T as ToolHost } from '../tool-host-C8JMMGYq.js';
|
|
2
|
+
import { B as Bridge } from '../types-DIVNcIQO.js';
|
|
3
|
+
import '../types-aOQLTW0E.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Headless bridge for `@particle-academy/fancy-catalog` — a Stripe catalog with
|
|
7
|
+
* NO UI surface. The adapter exposes the catalog's STORES + operations (not UI
|
|
8
|
+
* getters/setters), and the tools are CRUD over products / prices + checkout +
|
|
9
|
+
* Stripe sync. Mutations still funnel through `wrapToolWithActivity` so presence
|
|
10
|
+
* + undo compose, and the destructive delete is `pendingMode`-gated.
|
|
11
|
+
*
|
|
12
|
+
* The adapter shapes below are STRUCTURAL mirrors of fancy-catalog's public
|
|
13
|
+
* `Catalog` + store interfaces, defined LOCALLY so this bridge builds with the
|
|
14
|
+
* sibling package absent (it's an optional peer). A real `Catalog` instance is
|
|
15
|
+
* assignable to `CatalogBridgeAdapter` with no import — TypeScript is structural.
|
|
16
|
+
*/
|
|
17
|
+
/** Minimal product shape crossing the MCP wire (mirror of fancy-catalog `Product`). */
|
|
18
|
+
type CatalogProduct = {
|
|
19
|
+
id: string;
|
|
20
|
+
name: string;
|
|
21
|
+
description?: string | null;
|
|
22
|
+
active?: boolean;
|
|
23
|
+
lookupKey?: string | null;
|
|
24
|
+
externalId?: string | null;
|
|
25
|
+
metadata?: Record<string, unknown> | null;
|
|
26
|
+
[k: string]: unknown;
|
|
27
|
+
};
|
|
28
|
+
/** Minimal price shape crossing the MCP wire (mirror of fancy-catalog `Price`). */
|
|
29
|
+
type CatalogPrice = {
|
|
30
|
+
id: string;
|
|
31
|
+
productId: string;
|
|
32
|
+
active?: boolean;
|
|
33
|
+
currency: string;
|
|
34
|
+
unitAmount: number;
|
|
35
|
+
type: "recurring" | "one_time";
|
|
36
|
+
externalId?: string | null;
|
|
37
|
+
[k: string]: unknown;
|
|
38
|
+
};
|
|
39
|
+
/** Common checkout args (mirror of fancy-catalog `CheckoutArgs`). */
|
|
40
|
+
type CatalogCheckoutArgs = {
|
|
41
|
+
customer?: string;
|
|
42
|
+
successUrl: string;
|
|
43
|
+
cancelUrl: string;
|
|
44
|
+
metadata?: Record<string, string>;
|
|
45
|
+
/** One-time checkouts only. */
|
|
46
|
+
quantity?: number;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Adapter = the catalog instance / stores. A live `Catalog` from fancy-catalog
|
|
50
|
+
* satisfies this directly (`catalog.products`, `catalog.createProduct`, …); a
|
|
51
|
+
* host can also hand-roll one over its own persistence.
|
|
52
|
+
*/
|
|
53
|
+
type CatalogBridgeAdapter = {
|
|
54
|
+
/** Stable id for this catalog instance (multiple catalogs ⇒ distinct ids). */
|
|
55
|
+
id?: string;
|
|
56
|
+
/** Display label for logs / presence. */
|
|
57
|
+
title?: string;
|
|
58
|
+
/** Optional fancy-screens screen id (usually unset — this is headless). */
|
|
59
|
+
screenId?: string;
|
|
60
|
+
/** Product store — `catalog.products`. */
|
|
61
|
+
products: {
|
|
62
|
+
find(id: string, opts?: {
|
|
63
|
+
withTrashed?: boolean;
|
|
64
|
+
}): CatalogProduct | null | Promise<CatalogProduct | null>;
|
|
65
|
+
all(opts?: {
|
|
66
|
+
withTrashed?: boolean;
|
|
67
|
+
}): CatalogProduct[] | Promise<CatalogProduct[]>;
|
|
68
|
+
remove(id: string): void | Promise<void>;
|
|
69
|
+
};
|
|
70
|
+
/** Price store — `catalog.prices`. */
|
|
71
|
+
prices: {
|
|
72
|
+
find(id: string, opts?: {
|
|
73
|
+
withTrashed?: boolean;
|
|
74
|
+
}): CatalogPrice | null | Promise<CatalogPrice | null>;
|
|
75
|
+
forProduct(productId: string, opts?: {
|
|
76
|
+
withTrashed?: boolean;
|
|
77
|
+
}): CatalogPrice[] | Promise<CatalogPrice[]>;
|
|
78
|
+
all(opts?: {
|
|
79
|
+
withTrashed?: boolean;
|
|
80
|
+
}): CatalogPrice[] | Promise<CatalogPrice[]>;
|
|
81
|
+
remove(id: string): void | Promise<void>;
|
|
82
|
+
};
|
|
83
|
+
/** Authoring helpers — `catalog.createProduct` / `catalog.createPrice` (ULIDs auto-assigned). */
|
|
84
|
+
createProduct(input: Partial<CatalogProduct> & {
|
|
85
|
+
name: string;
|
|
86
|
+
}): Promise<CatalogProduct> | CatalogProduct;
|
|
87
|
+
createPrice(input: Partial<CatalogPrice> & {
|
|
88
|
+
productId: string;
|
|
89
|
+
currency: string;
|
|
90
|
+
unitAmount: number;
|
|
91
|
+
type: "recurring" | "one_time";
|
|
92
|
+
}): Promise<CatalogPrice> | CatalogPrice;
|
|
93
|
+
/** Stripe sync — `catalog.syncProductAndPrices`. Optional (no-op when absent). */
|
|
94
|
+
syncProductAndPrices?(product: CatalogProduct): Promise<CatalogProduct> | CatalogProduct;
|
|
95
|
+
/** Connection test — `catalog.testConnection`. Optional. */
|
|
96
|
+
testConnection?(): Promise<{
|
|
97
|
+
success: boolean;
|
|
98
|
+
message: string;
|
|
99
|
+
productCount?: number;
|
|
100
|
+
}> | {
|
|
101
|
+
success: boolean;
|
|
102
|
+
message: string;
|
|
103
|
+
productCount?: number;
|
|
104
|
+
};
|
|
105
|
+
/** Hosted Checkout — `catalog.getSubscriptionCheckoutUrl` / `getOneTimeCheckoutUrl`. Optional. */
|
|
106
|
+
getSubscriptionCheckoutUrl?(price: CatalogPrice, args: CatalogCheckoutArgs): Promise<string> | string;
|
|
107
|
+
getOneTimeCheckoutUrl?(price: CatalogPrice, args: CatalogCheckoutArgs): Promise<string> | string;
|
|
108
|
+
};
|
|
109
|
+
type CatalogBridgeOptions = {
|
|
110
|
+
adapter: CatalogBridgeAdapter;
|
|
111
|
+
/** Identity stamped on activity + undo entries. */
|
|
112
|
+
agent?: {
|
|
113
|
+
id: string;
|
|
114
|
+
name?: string;
|
|
115
|
+
color?: string;
|
|
116
|
+
};
|
|
117
|
+
/**
|
|
118
|
+
* Trust-but-verify. When on (default), destructive ops (`catalog_delete_product`,
|
|
119
|
+
* `catalog_delete_price`) route through `adapter`-less staging: they require an
|
|
120
|
+
* explicit `confirm: true` arg OR a host `confirm` callback. Read + create +
|
|
121
|
+
* checkout-url tools are unaffected.
|
|
122
|
+
*/
|
|
123
|
+
pendingMode?: boolean;
|
|
124
|
+
/** Host confirm hook for destructive ops (pendingMode). Resolves true to proceed. */
|
|
125
|
+
confirm?: (req: {
|
|
126
|
+
action: string;
|
|
127
|
+
id: string;
|
|
128
|
+
label: string;
|
|
129
|
+
}) => Promise<boolean> | boolean;
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* registerCatalogBridge — full MCP tool set over a headless Stripe catalog.
|
|
133
|
+
*
|
|
134
|
+
* catalog_list_products list products ({ id, name, active, priceCount })
|
|
135
|
+
* catalog_get_product full product JSON + its prices
|
|
136
|
+
* catalog_create_product create a product (ULID auto-assigned)
|
|
137
|
+
* catalog_delete_product soft-delete a product (pendingMode-gated, undoable*)
|
|
138
|
+
* catalog_list_prices list a product's prices (or all)
|
|
139
|
+
* catalog_create_price create a price under a product
|
|
140
|
+
* catalog_delete_price soft-delete a price (pendingMode-gated)
|
|
141
|
+
* catalog_sync_product push a product + its prices to Stripe
|
|
142
|
+
* catalog_test_connection verify the Stripe connection
|
|
143
|
+
* catalog_create_checkout build a hosted Checkout URL for a price
|
|
144
|
+
*
|
|
145
|
+
* *delete undo is best-effort: stores expose soft-delete (`remove`) but no
|
|
146
|
+
* un-delete, so the undo closure re-creates from the captured snapshot.
|
|
147
|
+
*/
|
|
148
|
+
declare function registerCatalogBridge(host: ToolHost, options: CatalogBridgeOptions): Bridge;
|
|
149
|
+
|
|
150
|
+
export { type CatalogBridgeAdapter, type CatalogBridgeOptions, type CatalogCheckoutArgs, type CatalogPrice, type CatalogProduct, registerCatalogBridge };
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { T as ToolHost } from '../tool-host-BQuUygLF.cjs';
|
|
2
|
+
import { B as Bridge } from '../types-CCSBGW9T.cjs';
|
|
3
|
+
import '../types-aOQLTW0E.cjs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Headless bridge for `@particle-academy/fancy-features` — feature management
|
|
7
|
+
* with NO UI surface. The adapter is the `FeatureManager` (a `FeatureSource`
|
|
8
|
+
* consumer): define features in the registry, check access for a subject,
|
|
9
|
+
* grant/revoke via group assignment, and meter resource usage. Mutations
|
|
10
|
+
* funnel through `wrapToolWithActivity` so presence + undo compose; `grant` /
|
|
11
|
+
* `revoke` are `pendingMode`-gated (they change what a real user can do).
|
|
12
|
+
*
|
|
13
|
+
* The adapter shapes mirror fancy-features' public `FeatureManager` +
|
|
14
|
+
* `FeatureRegistry` + `GroupStore`, defined LOCALLY so the bridge builds with
|
|
15
|
+
* the sibling absent (optional peer). A live `FeatureManager` (plus its
|
|
16
|
+
* `.registry` / `.groupStore`) satisfies this structurally with no import.
|
|
17
|
+
*
|
|
18
|
+
* SUBJECTS over the wire: `Subject` is opaque (`unknown`) in fancy-features.
|
|
19
|
+
* Agents pass a JSON-serializable subject (string id or `{ id, … }` object);
|
|
20
|
+
* the host's stores key on it via their `defaultSubjectKey`.
|
|
21
|
+
*/
|
|
22
|
+
type FeatureGrant = {
|
|
23
|
+
key: string;
|
|
24
|
+
type: "boolean" | "resource";
|
|
25
|
+
enabled: boolean;
|
|
26
|
+
includedQuantity?: number | null;
|
|
27
|
+
overageLimit?: number | null;
|
|
28
|
+
source?: string;
|
|
29
|
+
config?: Record<string, unknown>;
|
|
30
|
+
};
|
|
31
|
+
/** Normalized feature definition (mirror of fancy-features `FeatureDefinition`). */
|
|
32
|
+
type FeatureDefinition = {
|
|
33
|
+
key?: string;
|
|
34
|
+
name?: string;
|
|
35
|
+
description?: string;
|
|
36
|
+
type?: "boolean" | "resource";
|
|
37
|
+
enabled?: boolean;
|
|
38
|
+
limit?: number;
|
|
39
|
+
[k: string]: unknown;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Adapter = the `FeatureManager` + its registry + group store. The bridge only
|
|
43
|
+
* needs these members; a real manager exposes them directly.
|
|
44
|
+
*/
|
|
45
|
+
type FeaturesBridgeAdapter = {
|
|
46
|
+
/** Stable id for this feature manager instance. */
|
|
47
|
+
id?: string;
|
|
48
|
+
title?: string;
|
|
49
|
+
screenId?: string;
|
|
50
|
+
/** Can the subject access the feature now? `manager.canAccess`. */
|
|
51
|
+
canAccess(feature: string, subject?: unknown, context?: unknown): boolean | Promise<boolean>;
|
|
52
|
+
/** Remaining quota for a resource feature (null = unlimited / n-a). `manager.remaining`. */
|
|
53
|
+
remaining(feature: string, subject?: unknown, context?: unknown): number | null | Promise<number | null>;
|
|
54
|
+
/** All enabled feature keys for the subject. `manager.enabled`. */
|
|
55
|
+
enabled(subject?: unknown, context?: unknown): string[] | Promise<string[]>;
|
|
56
|
+
/** Trace a feature's resolution to an AccessResult. `manager.explain`. */
|
|
57
|
+
explain?(feature: string, subject?: unknown, context?: unknown): Promise<unknown> | unknown;
|
|
58
|
+
/** Register a programmatic feature. `manager.registerFeature` / `manager.registry.register`. */
|
|
59
|
+
registerFeature(key: string, definition: FeatureDefinition): void;
|
|
60
|
+
/** Registered feature keys. `manager.registry.keys`. */
|
|
61
|
+
registryKeys(): string[];
|
|
62
|
+
/** Resolve a registered definition (or null). `manager.registry.definition`. */
|
|
63
|
+
definition?(key: string): FeatureDefinition | null | Promise<FeatureDefinition | null>;
|
|
64
|
+
/** Assign a subject to a feature group (the grant primitive). `manager.groupStore.assign`. */
|
|
65
|
+
assignGroup(subject: unknown, groupKey: string): void | Promise<void>;
|
|
66
|
+
/** Detach a subject from a group (the revoke primitive). `manager.groupStore.detach`. */
|
|
67
|
+
detachGroup(subject: unknown, groupKey: string): void | Promise<void>;
|
|
68
|
+
/** Group keys assigned to a subject. `manager.groupStore.list`. */
|
|
69
|
+
listGroups(subject: unknown): string[] | Promise<string[]>;
|
|
70
|
+
/** Current usage for a resource feature. `manager.usageFor`. Optional. */
|
|
71
|
+
usageFor?(feature: string, subject: unknown): number | Promise<number>;
|
|
72
|
+
/** Atomic check-and-increment quota. `manager.tryConsume`. Optional. */
|
|
73
|
+
tryConsume?(feature: string, subject: unknown, amount?: number, context?: unknown): boolean | Promise<boolean>;
|
|
74
|
+
};
|
|
75
|
+
type FeaturesBridgeOptions = {
|
|
76
|
+
adapter: FeaturesBridgeAdapter;
|
|
77
|
+
agent?: {
|
|
78
|
+
id: string;
|
|
79
|
+
name?: string;
|
|
80
|
+
color?: string;
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Trust-but-verify. When on (default), `features_grant` / `features_revoke`
|
|
84
|
+
* (they change a real subject's entitlements) require `confirm:true` OR a
|
|
85
|
+
* host `confirm` hook. Checks + define + usage are unaffected.
|
|
86
|
+
*/
|
|
87
|
+
pendingMode?: boolean;
|
|
88
|
+
confirm?: (req: {
|
|
89
|
+
action: string;
|
|
90
|
+
subject: unknown;
|
|
91
|
+
groupKey: string;
|
|
92
|
+
}) => Promise<boolean> | boolean;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* registerFeaturesBridge — full MCP tool set over a headless feature manager.
|
|
96
|
+
*
|
|
97
|
+
* features_list enabled feature keys for a subject
|
|
98
|
+
* features_check can a subject access a feature? (+ remaining for resources)
|
|
99
|
+
* features_explain trace why a feature is on/off for a subject
|
|
100
|
+
* features_define register a feature definition (boolean / resource)
|
|
101
|
+
* features_grant assign a subject to a group (pendingMode-gated, undoable)
|
|
102
|
+
* features_revoke detach a subject from a group (pendingMode-gated, undoable)
|
|
103
|
+
* features_groups list a subject's assigned groups
|
|
104
|
+
* features_consume meter a resource feature (atomic check-and-increment)
|
|
105
|
+
*/
|
|
106
|
+
declare function registerFeaturesBridge(host: ToolHost, options: FeaturesBridgeOptions): Bridge;
|
|
107
|
+
|
|
108
|
+
export { type FeatureDefinition, type FeatureGrant, type FeaturesBridgeAdapter, type FeaturesBridgeOptions, registerFeaturesBridge };
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { T as ToolHost } from '../tool-host-C8JMMGYq.js';
|
|
2
|
+
import { B as Bridge } from '../types-DIVNcIQO.js';
|
|
3
|
+
import '../types-aOQLTW0E.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Headless bridge for `@particle-academy/fancy-features` — feature management
|
|
7
|
+
* with NO UI surface. The adapter is the `FeatureManager` (a `FeatureSource`
|
|
8
|
+
* consumer): define features in the registry, check access for a subject,
|
|
9
|
+
* grant/revoke via group assignment, and meter resource usage. Mutations
|
|
10
|
+
* funnel through `wrapToolWithActivity` so presence + undo compose; `grant` /
|
|
11
|
+
* `revoke` are `pendingMode`-gated (they change what a real user can do).
|
|
12
|
+
*
|
|
13
|
+
* The adapter shapes mirror fancy-features' public `FeatureManager` +
|
|
14
|
+
* `FeatureRegistry` + `GroupStore`, defined LOCALLY so the bridge builds with
|
|
15
|
+
* the sibling absent (optional peer). A live `FeatureManager` (plus its
|
|
16
|
+
* `.registry` / `.groupStore`) satisfies this structurally with no import.
|
|
17
|
+
*
|
|
18
|
+
* SUBJECTS over the wire: `Subject` is opaque (`unknown`) in fancy-features.
|
|
19
|
+
* Agents pass a JSON-serializable subject (string id or `{ id, … }` object);
|
|
20
|
+
* the host's stores key on it via their `defaultSubjectKey`.
|
|
21
|
+
*/
|
|
22
|
+
type FeatureGrant = {
|
|
23
|
+
key: string;
|
|
24
|
+
type: "boolean" | "resource";
|
|
25
|
+
enabled: boolean;
|
|
26
|
+
includedQuantity?: number | null;
|
|
27
|
+
overageLimit?: number | null;
|
|
28
|
+
source?: string;
|
|
29
|
+
config?: Record<string, unknown>;
|
|
30
|
+
};
|
|
31
|
+
/** Normalized feature definition (mirror of fancy-features `FeatureDefinition`). */
|
|
32
|
+
type FeatureDefinition = {
|
|
33
|
+
key?: string;
|
|
34
|
+
name?: string;
|
|
35
|
+
description?: string;
|
|
36
|
+
type?: "boolean" | "resource";
|
|
37
|
+
enabled?: boolean;
|
|
38
|
+
limit?: number;
|
|
39
|
+
[k: string]: unknown;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Adapter = the `FeatureManager` + its registry + group store. The bridge only
|
|
43
|
+
* needs these members; a real manager exposes them directly.
|
|
44
|
+
*/
|
|
45
|
+
type FeaturesBridgeAdapter = {
|
|
46
|
+
/** Stable id for this feature manager instance. */
|
|
47
|
+
id?: string;
|
|
48
|
+
title?: string;
|
|
49
|
+
screenId?: string;
|
|
50
|
+
/** Can the subject access the feature now? `manager.canAccess`. */
|
|
51
|
+
canAccess(feature: string, subject?: unknown, context?: unknown): boolean | Promise<boolean>;
|
|
52
|
+
/** Remaining quota for a resource feature (null = unlimited / n-a). `manager.remaining`. */
|
|
53
|
+
remaining(feature: string, subject?: unknown, context?: unknown): number | null | Promise<number | null>;
|
|
54
|
+
/** All enabled feature keys for the subject. `manager.enabled`. */
|
|
55
|
+
enabled(subject?: unknown, context?: unknown): string[] | Promise<string[]>;
|
|
56
|
+
/** Trace a feature's resolution to an AccessResult. `manager.explain`. */
|
|
57
|
+
explain?(feature: string, subject?: unknown, context?: unknown): Promise<unknown> | unknown;
|
|
58
|
+
/** Register a programmatic feature. `manager.registerFeature` / `manager.registry.register`. */
|
|
59
|
+
registerFeature(key: string, definition: FeatureDefinition): void;
|
|
60
|
+
/** Registered feature keys. `manager.registry.keys`. */
|
|
61
|
+
registryKeys(): string[];
|
|
62
|
+
/** Resolve a registered definition (or null). `manager.registry.definition`. */
|
|
63
|
+
definition?(key: string): FeatureDefinition | null | Promise<FeatureDefinition | null>;
|
|
64
|
+
/** Assign a subject to a feature group (the grant primitive). `manager.groupStore.assign`. */
|
|
65
|
+
assignGroup(subject: unknown, groupKey: string): void | Promise<void>;
|
|
66
|
+
/** Detach a subject from a group (the revoke primitive). `manager.groupStore.detach`. */
|
|
67
|
+
detachGroup(subject: unknown, groupKey: string): void | Promise<void>;
|
|
68
|
+
/** Group keys assigned to a subject. `manager.groupStore.list`. */
|
|
69
|
+
listGroups(subject: unknown): string[] | Promise<string[]>;
|
|
70
|
+
/** Current usage for a resource feature. `manager.usageFor`. Optional. */
|
|
71
|
+
usageFor?(feature: string, subject: unknown): number | Promise<number>;
|
|
72
|
+
/** Atomic check-and-increment quota. `manager.tryConsume`. Optional. */
|
|
73
|
+
tryConsume?(feature: string, subject: unknown, amount?: number, context?: unknown): boolean | Promise<boolean>;
|
|
74
|
+
};
|
|
75
|
+
type FeaturesBridgeOptions = {
|
|
76
|
+
adapter: FeaturesBridgeAdapter;
|
|
77
|
+
agent?: {
|
|
78
|
+
id: string;
|
|
79
|
+
name?: string;
|
|
80
|
+
color?: string;
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Trust-but-verify. When on (default), `features_grant` / `features_revoke`
|
|
84
|
+
* (they change a real subject's entitlements) require `confirm:true` OR a
|
|
85
|
+
* host `confirm` hook. Checks + define + usage are unaffected.
|
|
86
|
+
*/
|
|
87
|
+
pendingMode?: boolean;
|
|
88
|
+
confirm?: (req: {
|
|
89
|
+
action: string;
|
|
90
|
+
subject: unknown;
|
|
91
|
+
groupKey: string;
|
|
92
|
+
}) => Promise<boolean> | boolean;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* registerFeaturesBridge — full MCP tool set over a headless feature manager.
|
|
96
|
+
*
|
|
97
|
+
* features_list enabled feature keys for a subject
|
|
98
|
+
* features_check can a subject access a feature? (+ remaining for resources)
|
|
99
|
+
* features_explain trace why a feature is on/off for a subject
|
|
100
|
+
* features_define register a feature definition (boolean / resource)
|
|
101
|
+
* features_grant assign a subject to a group (pendingMode-gated, undoable)
|
|
102
|
+
* features_revoke detach a subject from a group (pendingMode-gated, undoable)
|
|
103
|
+
* features_groups list a subject's assigned groups
|
|
104
|
+
* features_consume meter a resource feature (atomic check-and-increment)
|
|
105
|
+
*/
|
|
106
|
+
declare function registerFeaturesBridge(host: ToolHost, options: FeaturesBridgeOptions): Bridge;
|
|
107
|
+
|
|
108
|
+
export { type FeatureDefinition, type FeatureGrant, type FeaturesBridgeAdapter, type FeaturesBridgeOptions, registerFeaturesBridge };
|