@retailcrm/embed-ui-v1-endpoint 0.9.22-alpha.3 → 0.9.22-alpha.5
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/bin/embed-ui-v1-endpoint.mjs +127 -19
- package/package.json +6 -7
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import fs from 'node:fs'
|
|
4
4
|
import path from 'node:path'
|
|
5
5
|
import process from 'node:process'
|
|
6
|
+
import { spawnSync } from 'node:child_process'
|
|
6
7
|
|
|
7
8
|
const PACKAGE_NAME = '@retailcrm/embed-ui-v1-endpoint'
|
|
8
9
|
const DEFAULT_NEWLINE = '\n'
|
|
@@ -10,20 +11,23 @@ const AGENTS_SECTION_HEADER = '## @retailcrm/embed-ui-v1-endpoint'
|
|
|
10
11
|
const README_MCP_SECTION_HEADER = '## MCP For AI Assistants'
|
|
11
12
|
const README_MCP_MARKER = 'embed-ui-v1-endpoint://targets'
|
|
12
13
|
const MCP_SERVER_NAME = 'retailcrm-embed-ui-v1-endpoint'
|
|
13
|
-
const
|
|
14
|
-
command: 'npx',
|
|
15
|
-
args: ['-y', '-p', PACKAGE_NAME, 'embed-ui-v1-endpoint-mcp'],
|
|
16
|
-
}
|
|
14
|
+
const MCP_BIN_NAME = process.platform === 'win32' ? 'embed-ui-v1-endpoint-mcp.cmd' : 'embed-ui-v1-endpoint-mcp'
|
|
17
15
|
const MCP_CLIENT_CONFIGS = {
|
|
16
|
+
codex: {
|
|
17
|
+
type: 'codex',
|
|
18
|
+
},
|
|
18
19
|
cursor: {
|
|
20
|
+
type: 'file',
|
|
19
21
|
filePath: '.cursor/mcp.json',
|
|
20
22
|
rootField: 'mcpServers',
|
|
21
23
|
},
|
|
22
24
|
junie: {
|
|
25
|
+
type: 'file',
|
|
23
26
|
filePath: '.junie/mcp/mcp.json',
|
|
24
27
|
rootField: 'mcpServers',
|
|
25
28
|
},
|
|
26
29
|
vscode: {
|
|
30
|
+
type: 'file',
|
|
27
31
|
filePath: '.vscode/mcp.json',
|
|
28
32
|
rootField: 'servers',
|
|
29
33
|
},
|
|
@@ -35,7 +39,7 @@ const HELP_TEXT = `Usage:
|
|
|
35
39
|
|
|
36
40
|
Options:
|
|
37
41
|
-f, --force Replace existing managed sections and MCP server entries
|
|
38
|
-
--mcp-client-configs Comma-separated MCP client configs to create (cursor,junie,vscode)
|
|
42
|
+
--mcp-client-configs Comma-separated MCP client configs to create (codex,cursor,junie,vscode)
|
|
39
43
|
--dry-run Print planned config changes without writing files
|
|
40
44
|
-h, --help Show this help
|
|
41
45
|
|
|
@@ -44,9 +48,30 @@ Examples:
|
|
|
44
48
|
npx ${PACKAGE_NAME} init-agents ./my-project
|
|
45
49
|
npx ${PACKAGE_NAME} init-agents --force
|
|
46
50
|
npx ${PACKAGE_NAME} init-config ./my-project
|
|
47
|
-
npx ${PACKAGE_NAME} init-config ./my-project --mcp-client-configs cursor,junie,vscode
|
|
51
|
+
npx ${PACKAGE_NAME} init-config ./my-project --mcp-client-configs codex,cursor,junie,vscode
|
|
48
52
|
`
|
|
49
53
|
|
|
54
|
+
const resolveLocalMcpBinPath = (target) => path.join(target, 'node_modules', '.bin', MCP_BIN_NAME)
|
|
55
|
+
|
|
56
|
+
const createMcpServerConfig = (target) => ({
|
|
57
|
+
command: resolveLocalMcpBinPath(target),
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
const formatShellCommand = (command, args = []) => [command, ...args].map((part) => part.includes(' ') ? `"${part}"` : part).join(' ')
|
|
61
|
+
|
|
62
|
+
const createCodexAddCommand = (target) => [
|
|
63
|
+
'codex',
|
|
64
|
+
'mcp',
|
|
65
|
+
'add',
|
|
66
|
+
MCP_SERVER_NAME,
|
|
67
|
+
'--',
|
|
68
|
+
resolveLocalMcpBinPath(target),
|
|
69
|
+
]
|
|
70
|
+
|
|
71
|
+
const printMcpNotice = (message) => {
|
|
72
|
+
console.log(`MCP: ${message}`)
|
|
73
|
+
}
|
|
74
|
+
|
|
50
75
|
const parseArgs = (argv) => {
|
|
51
76
|
const options = {
|
|
52
77
|
command: null,
|
|
@@ -128,15 +153,15 @@ When working with \`${PACKAGE_NAME}\` in this project:
|
|
|
128
153
|
5. When the task involves widget targets, target placement, target contexts, target metadata, or choosing a target, use the package MCP server if it is available.
|
|
129
154
|
6. First read \`embed-ui-v1-endpoint://targets\` to discover available target profiles.
|
|
130
155
|
7. Then read the relevant \`embed-ui-v1-endpoint://targets/<encoded-target>\` resource before answering or changing code related to that target.
|
|
131
|
-
8.
|
|
132
|
-
9.
|
|
156
|
+
8. A project \`.mcp.json\` may require restarting or reconnecting the AI client before MCP resources appear in the current session.
|
|
157
|
+
9. If MCP resources are not available, use the generated YAML profiles from \`./node_modules/${PACKAGE_NAME}/docs/targets/*.yml\` as the fallback source.
|
|
158
|
+
10. Prefer target profiles over guessing target placement, contexts, or semantic intent from names alone.
|
|
133
159
|
|
|
134
160
|
Suggested MCP stdio server configuration:
|
|
135
161
|
|
|
136
162
|
\`\`\`json
|
|
137
163
|
{
|
|
138
|
-
"command": "
|
|
139
|
-
"args": ["-y", "-p", "${PACKAGE_NAME}", "embed-ui-v1-endpoint-mcp"]
|
|
164
|
+
"command": "./node_modules/.bin/embed-ui-v1-endpoint-mcp"
|
|
140
165
|
}
|
|
141
166
|
\`\`\`
|
|
142
167
|
`
|
|
@@ -145,17 +170,19 @@ Suggested MCP stdio server configuration:
|
|
|
145
170
|
const createMcpReadmeSection = (clientConfigs) => {
|
|
146
171
|
const clientConfigText = clientConfigs.length
|
|
147
172
|
? `Client MCP configs were also requested: ${clientConfigs.map((clientConfig) => `\`${clientConfig}\``).join(', ')}. Review the generated files and restart the AI client if it is already open.`
|
|
148
|
-
: 'Client MCP configs are not created by default. For supported
|
|
173
|
+
: 'Client MCP configs are not created by default. For supported configs, rerun init with `--mcp-client-configs codex,cursor,junie,vscode`.'
|
|
149
174
|
|
|
150
175
|
return `${README_MCP_SECTION_HEADER}
|
|
151
176
|
|
|
152
177
|
The project has an MCP server configuration for \`${PACKAGE_NAME}\`.
|
|
153
178
|
It exposes AI-friendly widget target descriptions as MCP resources.
|
|
179
|
+
If the AI client was already running, restart or reconnect it before expecting these resources
|
|
180
|
+
to appear in that session.
|
|
154
181
|
|
|
155
182
|
Basic check:
|
|
156
183
|
|
|
157
184
|
\`\`\`bash
|
|
158
|
-
|
|
185
|
+
./node_modules/.bin/embed-ui-v1-endpoint-mcp
|
|
159
186
|
\`\`\`
|
|
160
187
|
|
|
161
188
|
Primary resources:
|
|
@@ -170,6 +197,21 @@ ${clientConfigText}
|
|
|
170
197
|
Some clients store MCP servers in a user-level config outside this repository. Init does not edit
|
|
171
198
|
those files. Add the same server manually and restart the client.
|
|
172
199
|
|
|
200
|
+
Codex CLI:
|
|
201
|
+
|
|
202
|
+
\`\`\`bash
|
|
203
|
+
codex mcp add ${MCP_SERVER_NAME} -- "$(realpath ./node_modules/.bin/embed-ui-v1-endpoint-mcp)"
|
|
204
|
+
codex mcp list
|
|
205
|
+
codex mcp get ${MCP_SERVER_NAME}
|
|
206
|
+
\`\`\`
|
|
207
|
+
|
|
208
|
+
Equivalent \`~/.codex/config.toml\` block:
|
|
209
|
+
|
|
210
|
+
\`\`\`toml
|
|
211
|
+
[mcp_servers.${MCP_SERVER_NAME}]
|
|
212
|
+
command = "/absolute/path/to/project/node_modules/.bin/embed-ui-v1-endpoint-mcp"
|
|
213
|
+
\`\`\`
|
|
214
|
+
|
|
173
215
|
Claude Desktop config paths:
|
|
174
216
|
|
|
175
217
|
- macOS: \`~/Library/Application Support/Claude/claude_desktop_config.json\`
|
|
@@ -181,8 +223,7 @@ Config snippet:
|
|
|
181
223
|
{
|
|
182
224
|
"mcpServers": {
|
|
183
225
|
"${MCP_SERVER_NAME}": {
|
|
184
|
-
"command": "
|
|
185
|
-
"args": ["-y", "-p", "${PACKAGE_NAME}", "embed-ui-v1-endpoint-mcp"]
|
|
226
|
+
"command": "/absolute/path/to/project/node_modules/.bin/embed-ui-v1-endpoint-mcp"
|
|
186
227
|
}
|
|
187
228
|
}
|
|
188
229
|
}
|
|
@@ -314,7 +355,7 @@ const initAgents = (target, force) => {
|
|
|
314
355
|
console.log(`The ${PACKAGE_NAME} instructions were appended to the end of the file.`)
|
|
315
356
|
}
|
|
316
357
|
|
|
317
|
-
const writeMcpServerConfig = (target, relativePath, rootField, options) => {
|
|
358
|
+
const writeMcpServerConfig = (target, relativePath, rootField, options, serverConfig) => {
|
|
318
359
|
const filePath = path.join(target, relativePath)
|
|
319
360
|
const fileExists = fs.existsSync(filePath)
|
|
320
361
|
const config = readJsonObject(filePath)
|
|
@@ -323,14 +364,69 @@ const writeMcpServerConfig = (target, relativePath, rootField, options) => {
|
|
|
323
364
|
if (servers[MCP_SERVER_NAME] && !options.force) {
|
|
324
365
|
console.log(`${relativePath} already contains ${MCP_SERVER_NAME}`)
|
|
325
366
|
console.log('Nothing was changed. Re-run with --force to refresh that server entry.')
|
|
326
|
-
return
|
|
367
|
+
return false
|
|
327
368
|
}
|
|
328
369
|
|
|
329
|
-
servers[MCP_SERVER_NAME] =
|
|
370
|
+
servers[MCP_SERVER_NAME] = serverConfig
|
|
330
371
|
writeJson(filePath, config, options.dryRun)
|
|
331
372
|
|
|
332
373
|
const action = fileExists ? 'updated' : 'created'
|
|
333
374
|
console.log(`${relativePath} ${options.dryRun ? `would be ${action}` : `was ${action}`}`)
|
|
375
|
+
return true
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
const isCodexMcpAddAvailable = () => {
|
|
379
|
+
const result = spawnSync('codex', ['mcp', 'add', '--help'], {
|
|
380
|
+
encoding: 'utf8',
|
|
381
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
382
|
+
})
|
|
383
|
+
|
|
384
|
+
return !result.error && result.status === 0
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
const runCodexMcpAdd = (target, options) => {
|
|
388
|
+
const localMcpBinPath = resolveLocalMcpBinPath(target)
|
|
389
|
+
const codexCommand = createCodexAddCommand(target)
|
|
390
|
+
const codexCommandText = formatShellCommand(codexCommand[0], codexCommand.slice(1))
|
|
391
|
+
|
|
392
|
+
if (!fs.existsSync(localMcpBinPath)) {
|
|
393
|
+
printMcpNotice(`Codex MCP auto-connect skipped: local MCP binary was not found at ${localMcpBinPath}. Run package install, then run: ${codexCommandText}`)
|
|
394
|
+
return
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
if (!isCodexMcpAddAvailable()) {
|
|
398
|
+
printMcpNotice(`Codex MCP auto-connect skipped: "codex mcp add" is not available. Run manually after installing Codex CLI support: ${codexCommandText}`)
|
|
399
|
+
return
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
if (options.dryRun) {
|
|
403
|
+
printMcpNotice(`Codex MCP server would be registered with local binary: ${codexCommandText}`)
|
|
404
|
+
return
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
const result = spawnSync(codexCommand[0], codexCommand.slice(1), {
|
|
408
|
+
encoding: 'utf8',
|
|
409
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
410
|
+
})
|
|
411
|
+
|
|
412
|
+
if (result.error || result.status !== 0) {
|
|
413
|
+
const output = [result.stderr, result.stdout]
|
|
414
|
+
.filter((value) => typeof value === 'string' && value.trim())
|
|
415
|
+
.map((value) => value.trim())
|
|
416
|
+
.join(' ')
|
|
417
|
+
|
|
418
|
+
printMcpNotice(`Codex MCP auto-connect failed${output ? `: ${output}` : ''}. Run manually: ${codexCommandText}`)
|
|
419
|
+
return
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
printMcpNotice('Codex MCP server was registered with the local v1-endpoint binary. Restart Codex session to use new resources.')
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
const printFileClientMcpNotice = (clientConfig, target) => {
|
|
426
|
+
const config = MCP_CLIENT_CONFIGS[clientConfig]
|
|
427
|
+
|
|
428
|
+
printMcpNotice(`${clientConfig} MCP config points to local binary ${resolveLocalMcpBinPath(target)}. Restart or reconnect the client to use new resources.`)
|
|
429
|
+
printMcpNotice(`${clientConfig} config file: ${path.join(target, config.filePath)}`)
|
|
334
430
|
}
|
|
335
431
|
|
|
336
432
|
const resolveMcpClientConfigs = (tokens) => {
|
|
@@ -379,12 +475,24 @@ const initConfig = (target, options) => {
|
|
|
379
475
|
}
|
|
380
476
|
|
|
381
477
|
const clientConfigs = resolveMcpClientConfigs(options.mcpClientConfigs)
|
|
478
|
+
const serverConfig = createMcpServerConfig(target)
|
|
382
479
|
|
|
383
|
-
writeMcpServerConfig(target, '.mcp.json', 'mcpServers', options)
|
|
480
|
+
writeMcpServerConfig(target, '.mcp.json', 'mcpServers', options, serverConfig)
|
|
481
|
+
printMcpNotice(`Project MCP config points to local binary ${serverConfig.command}. Restart or reconnect MCP clients to use new resources.`)
|
|
482
|
+
if (!fs.existsSync(serverConfig.command)) {
|
|
483
|
+
printMcpNotice(`Local MCP binary is not available yet. Install project dependencies before starting MCP clients: ${serverConfig.command}`)
|
|
484
|
+
}
|
|
384
485
|
|
|
385
486
|
for (const clientConfig of clientConfigs) {
|
|
386
487
|
const config = MCP_CLIENT_CONFIGS[clientConfig]
|
|
387
|
-
|
|
488
|
+
|
|
489
|
+
if (config.type === 'codex') {
|
|
490
|
+
runCodexMcpAdd(target, options)
|
|
491
|
+
continue
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
writeMcpServerConfig(target, config.filePath, config.rootField, options, serverConfig)
|
|
495
|
+
printFileClientMcpNotice(clientConfig, target)
|
|
388
496
|
}
|
|
389
497
|
|
|
390
498
|
updateMcpReadmeNotes(target, clientConfigs, options)
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"embed-ui-v1-endpoint-mcp": "./bin/embed-ui-v1-endpoint-mcp.mjs"
|
|
6
6
|
},
|
|
7
7
|
"type": "module",
|
|
8
|
-
"version": "0.9.22-alpha.
|
|
8
|
+
"version": "0.9.22-alpha.5",
|
|
9
9
|
"description": "Endpoint API for integrations in RetailCRM",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"author": "RetailDriverLLC <integration@retailcrm.ru>",
|
|
@@ -97,24 +97,23 @@
|
|
|
97
97
|
"peerDependencies": {
|
|
98
98
|
"@omnicajs/vue-remote": "^0.2.23",
|
|
99
99
|
"@remote-ui/rpc": "^1.4",
|
|
100
|
-
"@retailcrm/embed-ui-v1-contexts": "^0.9.22-alpha.
|
|
101
|
-
"@retailcrm/embed-ui-v1-types": "^0.9.22-alpha.
|
|
100
|
+
"@retailcrm/embed-ui-v1-contexts": "^0.9.22-alpha.5",
|
|
101
|
+
"@retailcrm/embed-ui-v1-types": "^0.9.22-alpha.5",
|
|
102
102
|
"pinia": "^2.2",
|
|
103
103
|
"vue": "^3.5"
|
|
104
104
|
},
|
|
105
105
|
"dependencies": {
|
|
106
106
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
107
107
|
"@remote-ui/rpc": "^1.4.7",
|
|
108
|
-
"@retailcrm/embed-ui-v1-components": "^0.9.22-alpha.
|
|
109
|
-
"@retailcrm/embed-ui-v1-contexts": "^0.9.22-alpha.
|
|
110
|
-
"@retailcrm/embed-ui-v1-types": "^0.9.22-alpha.
|
|
108
|
+
"@retailcrm/embed-ui-v1-components": "^0.9.22-alpha.5",
|
|
109
|
+
"@retailcrm/embed-ui-v1-contexts": "^0.9.22-alpha.5",
|
|
110
|
+
"@retailcrm/embed-ui-v1-types": "^0.9.22-alpha.5"
|
|
111
111
|
},
|
|
112
112
|
"devDependencies": {
|
|
113
113
|
"@retailcrm/image-preview": "^1.0.2",
|
|
114
114
|
"@vitest/browser": "4.1.3",
|
|
115
115
|
"@vitest/browser-playwright": "4.1.3",
|
|
116
116
|
"date-fns": "^4.1.0",
|
|
117
|
-
"lodash.isequal": "^4.5.0",
|
|
118
117
|
"playwright": "1.58.2",
|
|
119
118
|
"tsx": "^4.21.0",
|
|
120
119
|
"vite": "^7.3.2",
|