@retailcrm/embed-ui-v1-contexts 0.9.23-alpha.2 → 0.9.23

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.
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const fs = require("node:fs");
4
+ const process = require("node:process");
5
+ const node_url = require("node:url");
6
+ const node_path = require("node:path");
7
+ const mcp_js = require("@modelcontextprotocol/sdk/server/mcp.js");
8
+ const stdio_js = require("@modelcontextprotocol/sdk/server/stdio.js");
9
+ var _documentCurrentScript = typeof document !== "undefined" ? document.currentScript : null;
10
+ function _interopNamespaceDefault(e) {
11
+ const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
12
+ if (e) {
13
+ for (const k in e) {
14
+ if (k !== "default") {
15
+ const d = Object.getOwnPropertyDescriptor(e, k);
16
+ Object.defineProperty(n, k, d.get ? d : {
17
+ enumerable: true,
18
+ get: () => e[k]
19
+ });
20
+ }
21
+ }
22
+ }
23
+ n.default = e;
24
+ return Object.freeze(n);
25
+ }
26
+ const fs__namespace = /* @__PURE__ */ _interopNamespaceDefault(fs);
27
+ const packageRoot = node_path.resolve(node_path.dirname(node_url.fileURLToPath(typeof document === "undefined" ? require("url").pathToFileURL(__filename).href : _documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === "SCRIPT" && _documentCurrentScript.src || new URL("server.cjs", document.baseURI).href)), "../..");
28
+ const packageJson = node_path.join(packageRoot, "package.json");
29
+ const groups = [{
30
+ kind: "contexts",
31
+ indexUri: "embed-ui-v1-contexts://contexts",
32
+ title: "v1-contexts predefined contexts index",
33
+ description: "Machine-readable index of predefined context profiles provided by @retailcrm/embed-ui-v1-contexts.",
34
+ profileTitle: (id) => `Context ${id}`,
35
+ profileDescription: (id) => `AI-friendly YAML profile for predefined context ${id}.`
36
+ }, {
37
+ kind: "actions",
38
+ indexUri: "embed-ui-v1-contexts://actions",
39
+ title: "v1-contexts action scopes index",
40
+ description: "Machine-readable index of action scope profiles provided by @retailcrm/embed-ui-v1-contexts.",
41
+ profileTitle: (id) => `Action scope ${id}`,
42
+ profileDescription: (id) => `AI-friendly YAML profile for action scope ${id}.`
43
+ }, {
44
+ kind: "custom-contexts",
45
+ indexUri: "embed-ui-v1-contexts://custom-contexts",
46
+ title: "v1-contexts custom contexts index",
47
+ description: "Machine-readable index of custom context profiles provided by @retailcrm/embed-ui-v1-contexts.",
48
+ profileTitle: (id) => `Custom context ${id}`,
49
+ profileDescription: (id) => `AI-friendly YAML profile for custom context entity ${id}.`
50
+ }];
51
+ const readPackageVersion = () => {
52
+ const content = fs__namespace.readFileSync(packageJson, "utf8");
53
+ return JSON.parse(content).version;
54
+ };
55
+ const readIndex = (kind) => {
56
+ const index = node_path.join(packageRoot, "docs", kind, "index.json");
57
+ if (!fs__namespace.existsSync(index)) {
58
+ return {
59
+ package: "@retailcrm/embed-ui-v1-contexts",
60
+ resources: []
61
+ };
62
+ }
63
+ return JSON.parse(fs__namespace.readFileSync(index, "utf8"));
64
+ };
65
+ const readProfileResources = (kind) => {
66
+ return readIndex(kind).resources.map((resource) => ({
67
+ ...resource,
68
+ content: fs__namespace.readFileSync(node_path.join(packageRoot, resource.file), "utf8")
69
+ }));
70
+ };
71
+ const waitForCloseSignal = () => {
72
+ const keepAlive = setInterval(() => void 0, 2 ** 31 - 1);
73
+ process.stdin.resume();
74
+ return new Promise((resolve2) => {
75
+ const close = () => {
76
+ clearInterval(keepAlive);
77
+ resolve2();
78
+ };
79
+ process.once("SIGINT", close);
80
+ process.once("SIGTERM", close);
81
+ });
82
+ };
83
+ const createContextsMcpServer = () => {
84
+ const server = new mcp_js.McpServer({
85
+ name: "@retailcrm/embed-ui-v1-contexts",
86
+ version: readPackageVersion()
87
+ });
88
+ const compatibilityTool = server.registerTool("mcp-compatibility-noop", {
89
+ description: "Disabled compatibility tool used only to make tools/list return an empty list for clients that probe it."
90
+ }, () => ({
91
+ content: []
92
+ }));
93
+ const compatibilityPrompt = server.registerPrompt("mcp-compatibility-noop", {
94
+ description: "Disabled compatibility prompt used only to make prompts/list return an empty list for clients that probe it."
95
+ }, () => ({
96
+ messages: []
97
+ }));
98
+ compatibilityTool.disable();
99
+ compatibilityPrompt.disable();
100
+ for (const group of groups) {
101
+ const resources = readProfileResources(group.kind);
102
+ server.registerResource(`v1-contexts ${group.kind} index`, group.indexUri, {
103
+ title: group.title,
104
+ description: group.description,
105
+ mimeType: "application/json"
106
+ }, (uri) => ({
107
+ contents: [{
108
+ uri: uri.href,
109
+ mimeType: "application/json",
110
+ text: JSON.stringify({
111
+ package: "@retailcrm/embed-ui-v1-contexts",
112
+ resources: resources.map((resource) => ({
113
+ id: resource.id,
114
+ uri: resource.uri,
115
+ file: resource.file
116
+ }))
117
+ }, null, 2)
118
+ }]
119
+ }));
120
+ for (const resource of resources) {
121
+ server.registerResource(`v1-contexts ${group.kind} ${resource.id}`, resource.uri, {
122
+ title: group.profileTitle(resource.id),
123
+ description: group.profileDescription(resource.id),
124
+ mimeType: "application/yaml",
125
+ annotations: {
126
+ audience: ["assistant"],
127
+ priority: 0.8
128
+ }
129
+ }, (uri) => ({
130
+ contents: [{
131
+ uri: uri.href,
132
+ mimeType: "application/yaml",
133
+ text: resource.content
134
+ }]
135
+ }));
136
+ }
137
+ }
138
+ return server;
139
+ };
140
+ const runContextsMcpServer = async () => {
141
+ const server = createContextsMcpServer();
142
+ await server.connect(new stdio_js.StdioServerTransport());
143
+ await waitForCloseSignal();
144
+ await server.close();
145
+ };
146
+ exports.createContextsMcpServer = createContextsMcpServer;
147
+ exports.runContextsMcpServer = runContextsMcpServer;
@@ -0,0 +1,3 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare const createContextsMcpServer: () => McpServer;
3
+ export declare const runContextsMcpServer: () => Promise<void>;
@@ -0,0 +1,129 @@
1
+ import * as fs from "node:fs";
2
+ import process from "node:process";
3
+ import { fileURLToPath } from "node:url";
4
+ import { resolve, dirname, join } from "node:path";
5
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
6
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
7
+ const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), "../..");
8
+ const packageJson = join(packageRoot, "package.json");
9
+ const groups = [{
10
+ kind: "contexts",
11
+ indexUri: "embed-ui-v1-contexts://contexts",
12
+ title: "v1-contexts predefined contexts index",
13
+ description: "Machine-readable index of predefined context profiles provided by @retailcrm/embed-ui-v1-contexts.",
14
+ profileTitle: (id) => `Context ${id}`,
15
+ profileDescription: (id) => `AI-friendly YAML profile for predefined context ${id}.`
16
+ }, {
17
+ kind: "actions",
18
+ indexUri: "embed-ui-v1-contexts://actions",
19
+ title: "v1-contexts action scopes index",
20
+ description: "Machine-readable index of action scope profiles provided by @retailcrm/embed-ui-v1-contexts.",
21
+ profileTitle: (id) => `Action scope ${id}`,
22
+ profileDescription: (id) => `AI-friendly YAML profile for action scope ${id}.`
23
+ }, {
24
+ kind: "custom-contexts",
25
+ indexUri: "embed-ui-v1-contexts://custom-contexts",
26
+ title: "v1-contexts custom contexts index",
27
+ description: "Machine-readable index of custom context profiles provided by @retailcrm/embed-ui-v1-contexts.",
28
+ profileTitle: (id) => `Custom context ${id}`,
29
+ profileDescription: (id) => `AI-friendly YAML profile for custom context entity ${id}.`
30
+ }];
31
+ const readPackageVersion = () => {
32
+ const content = fs.readFileSync(packageJson, "utf8");
33
+ return JSON.parse(content).version;
34
+ };
35
+ const readIndex = (kind) => {
36
+ const index = join(packageRoot, "docs", kind, "index.json");
37
+ if (!fs.existsSync(index)) {
38
+ return {
39
+ package: "@retailcrm/embed-ui-v1-contexts",
40
+ resources: []
41
+ };
42
+ }
43
+ return JSON.parse(fs.readFileSync(index, "utf8"));
44
+ };
45
+ const readProfileResources = (kind) => {
46
+ return readIndex(kind).resources.map((resource) => ({
47
+ ...resource,
48
+ content: fs.readFileSync(join(packageRoot, resource.file), "utf8")
49
+ }));
50
+ };
51
+ const waitForCloseSignal = () => {
52
+ const keepAlive = setInterval(() => void 0, 2 ** 31 - 1);
53
+ process.stdin.resume();
54
+ return new Promise((resolve2) => {
55
+ const close = () => {
56
+ clearInterval(keepAlive);
57
+ resolve2();
58
+ };
59
+ process.once("SIGINT", close);
60
+ process.once("SIGTERM", close);
61
+ });
62
+ };
63
+ const createContextsMcpServer = () => {
64
+ const server = new McpServer({
65
+ name: "@retailcrm/embed-ui-v1-contexts",
66
+ version: readPackageVersion()
67
+ });
68
+ const compatibilityTool = server.registerTool("mcp-compatibility-noop", {
69
+ description: "Disabled compatibility tool used only to make tools/list return an empty list for clients that probe it."
70
+ }, () => ({
71
+ content: []
72
+ }));
73
+ const compatibilityPrompt = server.registerPrompt("mcp-compatibility-noop", {
74
+ description: "Disabled compatibility prompt used only to make prompts/list return an empty list for clients that probe it."
75
+ }, () => ({
76
+ messages: []
77
+ }));
78
+ compatibilityTool.disable();
79
+ compatibilityPrompt.disable();
80
+ for (const group of groups) {
81
+ const resources = readProfileResources(group.kind);
82
+ server.registerResource(`v1-contexts ${group.kind} index`, group.indexUri, {
83
+ title: group.title,
84
+ description: group.description,
85
+ mimeType: "application/json"
86
+ }, (uri) => ({
87
+ contents: [{
88
+ uri: uri.href,
89
+ mimeType: "application/json",
90
+ text: JSON.stringify({
91
+ package: "@retailcrm/embed-ui-v1-contexts",
92
+ resources: resources.map((resource) => ({
93
+ id: resource.id,
94
+ uri: resource.uri,
95
+ file: resource.file
96
+ }))
97
+ }, null, 2)
98
+ }]
99
+ }));
100
+ for (const resource of resources) {
101
+ server.registerResource(`v1-contexts ${group.kind} ${resource.id}`, resource.uri, {
102
+ title: group.profileTitle(resource.id),
103
+ description: group.profileDescription(resource.id),
104
+ mimeType: "application/yaml",
105
+ annotations: {
106
+ audience: ["assistant"],
107
+ priority: 0.8
108
+ }
109
+ }, (uri) => ({
110
+ contents: [{
111
+ uri: uri.href,
112
+ mimeType: "application/yaml",
113
+ text: resource.content
114
+ }]
115
+ }));
116
+ }
117
+ }
118
+ return server;
119
+ };
120
+ const runContextsMcpServer = async () => {
121
+ const server = createContextsMcpServer();
122
+ await server.connect(new StdioServerTransport());
123
+ await waitForCloseSignal();
124
+ await server.close();
125
+ };
126
+ export {
127
+ createContextsMcpServer,
128
+ runContextsMcpServer
129
+ };
package/dist/meta.json CHANGED
@@ -1570,9 +1570,9 @@
1570
1570
  "name": "image.workers",
1571
1571
  "type": "Array<string>",
1572
1572
  "description": {
1573
- "en-GB": "A list of servers that process images.",
1574
- "es-ES": "Una lista de servidores que procesan imágenes.",
1575
- "ru-RU": "Список серверов, обрабатывающих изображения."
1573
+ "en-GB": "List of image preview worker hosts used to build resized or cropped image URLs.",
1574
+ "es-ES": "Lista de hosts de workers de previsualización de imágenes usados para crear URLs de imágenes redimensionadas o recortadas.",
1575
+ "ru-RU": "Список host-ов image preview workers для построения URL уменьшенных или обрезанных изображений."
1576
1576
  },
1577
1577
  "readonly": true
1578
1578
  },
@@ -0,0 +1,10 @@
1
+ {
2
+ "package": "@retailcrm/embed-ui-v1-contexts",
3
+ "resources": [
4
+ {
5
+ "id": "order/card",
6
+ "uri": "embed-ui-v1-contexts://actions/order%2Fcard",
7
+ "file": "docs/actions/order-card.yml"
8
+ }
9
+ ]
10
+ }
@@ -0,0 +1,107 @@
1
+ "action_scope": "order/card"
2
+ "summary": "Order card actions for mutating order items through the host form contract."
3
+ "language": "en-GB"
4
+ "audience": "ai"
5
+ "actions":
6
+ -
7
+ "name": "createItem"
8
+ "arguments":
9
+ -
10
+ "name": "input"
11
+ "type": "CreateOrderItemInput"
12
+ "returns": "Promise<number>"
13
+ "description": "Creates and adds a new item to the order"
14
+ "mutates":
15
+ - "items"
16
+ "ai_notes":
17
+ - "Use when a widget needs to add a product or service to the order form."
18
+ -
19
+ "name": "changeItemPrice"
20
+ "arguments":
21
+ -
22
+ "name": "index"
23
+ "type": "number"
24
+ -
25
+ "name": "amount"
26
+ "type": "number"
27
+ "returns": "Promise<void>"
28
+ "description": "Changes the price value of an item"
29
+ "mutates":
30
+ - "items[].initialPrice"
31
+ "ai_notes":
32
+ - "Use with OrderItem.index when changing item price."
33
+ -
34
+ "name": "changeItemPriceType"
35
+ "arguments":
36
+ -
37
+ "name": "index"
38
+ "type": "number"
39
+ -
40
+ "name": "code"
41
+ "type": "string|null"
42
+ "returns": "Promise<void>"
43
+ "description": "Changes the price type value of an item, changes the price if the new price type is not empty"
44
+ "mutates":
45
+ - "items[].priceType"
46
+ "ai_notes":
47
+ - "Use with OrderItem.index when changing item price type."
48
+ -
49
+ "name": "changeItemDiscount"
50
+ "arguments":
51
+ -
52
+ "name": "index"
53
+ "type": "number"
54
+ -
55
+ "name": "discount"
56
+ "type": "{ amount: number|undefined, percent: number|undefined }"
57
+ "returns": "Promise<void>"
58
+ "description": "Changes the discount value of an item"
59
+ "mutates":
60
+ - "items[].discounts"
61
+ - "items[].discountTotal"
62
+ "ai_notes":
63
+ - "Use with OrderItem.index when changing item discount."
64
+ -
65
+ "name": "changeItemQuantity"
66
+ "arguments":
67
+ -
68
+ "name": "index"
69
+ "type": "number"
70
+ -
71
+ "name": "quantity"
72
+ "type": "number"
73
+ "returns": "Promise<void>"
74
+ "description": "Changes the quantity of an item"
75
+ "mutates":
76
+ - "items[].quantity"
77
+ "ai_notes":
78
+ - "Use with OrderItem.index when changing item quantity."
79
+ -
80
+ "name": "changeItemStatus"
81
+ "arguments":
82
+ -
83
+ "name": "index"
84
+ "type": "number"
85
+ -
86
+ "name": "statusCode"
87
+ "type": "string"
88
+ "returns": "Promise<void>"
89
+ "description": "Changes the status of an item by specified identifier"
90
+ "mutates":
91
+ - "items[].status"
92
+ "ai_notes":
93
+ - "Use with OrderItem.index when changing item status."
94
+ -
95
+ "name": "removeItem"
96
+ "arguments":
97
+ -
98
+ "name": "index"
99
+ "type": "number"
100
+ "returns": "Promise<void>"
101
+ "description": "Removes an item from the order"
102
+ "mutates":
103
+ - "items"
104
+ "ai_notes":
105
+ - "Use with OrderItem.index when removing an item from the order."
106
+ "ai_notes":
107
+ - "Use actions for host-mediated mutations that cannot be performed by direct context field writes."
@@ -0,0 +1,37 @@
1
+ "context": "customer/card:phone"
2
+ "summary": "Readonly context for a single customer phone row target with phone value and row index."
3
+ "language": "en-GB"
4
+ "audience": "ai"
5
+ "public_import":
6
+ "usage_import": "import { useContext } from '@retailcrm/embed-ui-v1-contexts/remote/customer/card-phone'"
7
+ "usage_call": "const phone = useContext()"
8
+ "fields":
9
+ -
10
+ "name": "value"
11
+ "type": "string"
12
+ "readonly": true
13
+ "description": "Customer phone"
14
+ "source_of_truth": "Phone number value for the phone row where the widget is mounted."
15
+ "mutation":
16
+ "mode": "readonly"
17
+ "notes": "Readonly context field; use it for reading and UI calculations."
18
+ "related_actions": []
19
+ "ai_notes": []
20
+ -
21
+ "name": "index"
22
+ "type": "number"
23
+ "readonly": true
24
+ "description": "Serial number of the phone in the list"
25
+ "source_of_truth": "Zero-based position of the phone row inside the customer phone list."
26
+ "mutation":
27
+ "mode": "readonly"
28
+ "notes": "Readonly context field; use it for reading and UI calculations."
29
+ "related_actions": []
30
+ "ai_notes": []
31
+ "field_groups": []
32
+ "types": []
33
+ "usage":
34
+ "import": "import { useContext } from '@retailcrm/embed-ui-v1-contexts/remote/customer/card-phone'"
35
+ "call": "const phone = useContext()"
36
+ "related_actions": []
37
+ "ai_notes": []
@@ -0,0 +1,59 @@
1
+ "context": "customer/card"
2
+ "summary": "Readonly customer card context with customer identifiers, primary email, and phone list."
3
+ "language": "en-GB"
4
+ "audience": "ai"
5
+ "public_import":
6
+ "usage_import": "import { useContext } from '@retailcrm/embed-ui-v1-contexts/remote/customer/card'"
7
+ "usage_call": "const customer = useContext()"
8
+ "fields":
9
+ -
10
+ "name": "id"
11
+ "type": "number|null"
12
+ "readonly": true
13
+ "description": "Customer ID"
14
+ "source_of_truth": "CRM customer identifier for the opened customer card."
15
+ "mutation":
16
+ "mode": "readonly"
17
+ "notes": "Readonly context field; use it for reading and UI calculations."
18
+ "related_actions": []
19
+ "ai_notes": []
20
+ -
21
+ "name": "externalId"
22
+ "type": "string"
23
+ "readonly": true
24
+ "description": "Customer external ID"
25
+ "source_of_truth": "External customer identifier from the source system."
26
+ "mutation":
27
+ "mode": "readonly"
28
+ "notes": "Readonly context field; use it for reading and UI calculations."
29
+ "related_actions": []
30
+ "ai_notes": []
31
+ -
32
+ "name": "email"
33
+ "type": "string"
34
+ "readonly": true
35
+ "description": "Customer email"
36
+ "mutation":
37
+ "mode": "readonly"
38
+ "notes": "Readonly context field; use it for reading and UI calculations."
39
+ "related_actions": []
40
+ "ai_notes":
41
+ - "Use as the current customer email shown on the customer card; it is not a writable order-form field."
42
+ -
43
+ "name": "phones"
44
+ "type": "Array<string>"
45
+ "readonly": true
46
+ "description": "Customer phone list"
47
+ "mutation":
48
+ "mode": "readonly"
49
+ "notes": "Readonly context field; use it for reading and UI calculations."
50
+ "related_actions": []
51
+ "ai_notes":
52
+ - "Use for customer-card phone display and selection logic. For a widget attached to one phone row, prefer the customer/card:phone context."
53
+ "field_groups": []
54
+ "types": []
55
+ "usage":
56
+ "import": "import { useContext } from '@retailcrm/embed-ui-v1-contexts/remote/customer/card'"
57
+ "call": "const customer = useContext()"
58
+ "related_actions": []
59
+ "ai_notes": []
@@ -0,0 +1,35 @@
1
+ {
2
+ "package": "@retailcrm/embed-ui-v1-contexts",
3
+ "resources": [
4
+ {
5
+ "id": "customer/card",
6
+ "uri": "embed-ui-v1-contexts://contexts/customer%2Fcard",
7
+ "file": "docs/contexts/customer-card.yml"
8
+ },
9
+ {
10
+ "id": "customer/card:phone",
11
+ "uri": "embed-ui-v1-contexts://contexts/customer%2Fcard%3Aphone",
12
+ "file": "docs/contexts/customer-card-phone.yml"
13
+ },
14
+ {
15
+ "id": "order/card",
16
+ "uri": "embed-ui-v1-contexts://contexts/order%2Fcard",
17
+ "file": "docs/contexts/order-card.yml"
18
+ },
19
+ {
20
+ "id": "order/card:settings",
21
+ "uri": "embed-ui-v1-contexts://contexts/order%2Fcard%3Asettings",
22
+ "file": "docs/contexts/order-card-settings.yml"
23
+ },
24
+ {
25
+ "id": "user/current",
26
+ "uri": "embed-ui-v1-contexts://contexts/user%2Fcurrent",
27
+ "file": "docs/contexts/user-current.yml"
28
+ },
29
+ {
30
+ "id": "settings",
31
+ "uri": "embed-ui-v1-contexts://contexts/settings",
32
+ "file": "docs/contexts/settings.yml"
33
+ }
34
+ ]
35
+ }