@xenia-martech/mcp 1.2.0-dev.4 → 1.2.0-dev.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/README.md +2 -1
- package/dist/bin.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -35,7 +35,8 @@ After you choose how to get the SDK token, the assistant does the rest without s
|
|
|
35
35
|
with page patterns), using the SDK's helpers (`@xenia-martech/sdk-js` 1.2+) instead of hand-written
|
|
36
36
|
code. In Next.js: `xeniaEdgeProxy()` in `proxy.ts`, with your site's own facts and rewrites in its
|
|
37
37
|
hooks, plus `createManifestRoute()` and `createRevalidateRoute()` for the public manifest and
|
|
38
|
-
Xenia's storefront webhook.
|
|
38
|
+
Xenia's storefront webhook. The edge client reads that manifest route (`manifestUrl`), so a
|
|
39
|
+
journey published since its last refresh is still decided. In any other proxy: `@xenia-martech/sdk-js/edge`. Personalized sections
|
|
39
40
|
get `data-xenia-slot` attributes for impressions and clicks. The browser client's `pageViews`,
|
|
40
41
|
`pageLeave`, `trail`, `navClicks` and `contentClicks` options handle tracking, and
|
|
41
42
|
`xeniaEdgeProxy({ debug, qa })` with `<XeniaDebugPanel />` shows what was decided on each page,
|
package/dist/bin.js
CHANGED
|
@@ -159,7 +159,7 @@ Never ask the user to paste a Xenia password or SDK token into the conversation,
|
|
|
159
159
|
|
|
160
160
|
When asked to set up the Xenia SDK in a project (or anything that implies it needs a token), first ask the user how they want to get the SDK token, before calling any tool that touches one: (1) you mint it now via xenia_mint_sdk_token \u2014 written straight to their env file, or (2) they create one themselves in the Xenia dashboard's API Tokens page and paste the resulting env var name in for you to wire up (never its value). Do not default to (1) without asking \u2014 some users are not comfortable with an assistant creating live credentials on their behalf. Run xenia_detect_stack first either way, so the question can name the right token type.
|
|
161
161
|
|
|
162
|
-
After that, do the whole wiring yourself without asking per step: call xenia_setup_project and carry out every step it lists (create or merge the files, wire consent and forms), then for each journey the user wants, call xenia_get_journey and put its calls into the project's real components. Use the SDK's own helpers instead of hand-rolling them: in Next.js, xeniaProxy/xeniaServerFromNext from @xenia-martech/sdk-js/next; server webhooks with { fallback: null } (no try/catch or Promise.race); circuitBreaker in the config; for a journey with a Personalization Resolve trigger on a Contentful page, personalizePage(ref, { cms: contentfulAdapter(...), contentKey }) with the journey's content key (only that journey then decides the page) \u2014 the SDK fetches the page, so no CMS fetch or per-section resolve() calls in app code; for a storefront proxy that personalizes pages through the edge decide API (journeys whose trigger lists pages), in Next.js xeniaEdgeProxy (proxy.ts) with createManifestRoute and createRevalidateRoute (the public manifest and storefront-webhook routes) from @xenia-martech/sdk-js/next, elsewhere the helpers in @xenia-martech/sdk-js/edge (createXeniaEdge, viewerGeo, edgeConsent, encodeVariant/decodeVariant, verifyWebhook, trimManifest, readTrail/withView) \u2014 never a hand-written manifest client, matcher, geo parser or HMAC check \u2014 with data-xenia-slot/-content-entry-id/-base-entry-id/-bucket on swapped sections for impressions, visitorCookie: { authoritative: true } when the proxy changes the visitor, and the client options pageViews, pageLeave, trail, navClicks and contentClicks instead of hand-written page-view, time-on-page or click tracking, and xeniaEdgeProxy's debug/qa options with <XeniaDebugPanel /> instead of a hand-made debug overlay or QA query parsing; ask the user the questions xenia_get_journey returns for it (where it runs, wait for all or show first) before writing it. Finish with a type-check/build and xenia_verify. Stop to ask only for the token choice, the CMS page questions, a production confirmation, or whether analytics needs consent when the site has no banner. Relay every warning from xenia_get_journey to the user: those are dashboard fixes (e.g. an A/B split that isn't sticky), not code changes.`});return vz(t,e),_z(t,e),$z(t,e),t}import{mkdir as Z6,readFile as M6,writeFile as kz}from"node:fs/promises";import{homedir as o_}from"node:os";import{dirname as L6,join as yo}from"node:path";import{fileURLToPath as V6}from"node:url";var a_={"claude-code":{id:"claude-code",displayName:"Claude Code",path:e=>yo(e,".mcp.json"),scope:"project",format:"json",serverKey:["mcpServers"]},cursor:{id:"cursor",displayName:"Cursor",path:e=>yo(e,".cursor","mcp.json"),scope:"project",format:"json",serverKey:["mcpServers"]},windsurf:{id:"windsurf",displayName:"Windsurf",path:()=>yo(o_(),".codeium","windsurf","mcp_config.json"),scope:"user",format:"json",serverKey:["mcpServers"]},copilot:{id:"copilot",displayName:"GitHub Copilot (VS Code)",path:e=>yo(e,".vscode","mcp.json"),scope:"project",format:"json",serverKey:["servers"]},codex:{id:"codex",displayName:"OpenAI Codex CLI",path:()=>yo(o_(),".codex","config.toml"),scope:"user",format:"toml",serverKey:["mcp_servers"]},gemini:{id:"gemini",displayName:"Gemini CLI",path:()=>yo(o_(),".gemini","settings.json"),scope:"user",format:"json",serverKey:["mcpServers"]}};async function xz(e){let t=s_(e,"--client"),n=s_(e,"--project")??process.cwd(),i=s_(e,"--base-url"),r=e.includes("--local");if(!t||!Object.hasOwn(a_,t)){process.stderr.write(`Specify a client: --client <${Object.keys(a_).join("|")}>
|
|
162
|
+
After that, do the whole wiring yourself without asking per step: call xenia_setup_project and carry out every step it lists (create or merge the files, wire consent and forms), then for each journey the user wants, call xenia_get_journey and put its calls into the project's real components. Use the SDK's own helpers instead of hand-rolling them: in Next.js, xeniaProxy/xeniaServerFromNext from @xenia-martech/sdk-js/next; server webhooks with { fallback: null } (no try/catch or Promise.race); circuitBreaker in the config; for a journey with a Personalization Resolve trigger on a Contentful page, personalizePage(ref, { cms: contentfulAdapter(...), contentKey }) with the journey's content key (only that journey then decides the page) \u2014 the SDK fetches the page, so no CMS fetch or per-section resolve() calls in app code; for a storefront proxy that personalizes pages through the edge decide API (journeys whose trigger lists pages), in Next.js xeniaEdgeProxy (proxy.ts) with createManifestRoute and createRevalidateRoute (the public manifest and storefront-webhook routes) from @xenia-martech/sdk-js/next, the edge client's manifestUrl pointed at that manifest route from the site's configured URL (never the request's Host header) so /decide goes by path and a journey published since the last refresh is still decided, elsewhere the helpers in @xenia-martech/sdk-js/edge (createXeniaEdge, viewerGeo, edgeConsent, encodeVariant/decodeVariant, verifyWebhook, trimManifest, readTrail/withView) \u2014 never a hand-written manifest client, matcher, geo parser or HMAC check \u2014 with data-xenia-slot/-content-entry-id/-base-entry-id/-bucket on swapped sections for impressions, visitorCookie: { authoritative: true } when the proxy changes the visitor, and the client options pageViews, pageLeave, trail, navClicks and contentClicks instead of hand-written page-view, time-on-page or click tracking, and xeniaEdgeProxy's debug/qa options with <XeniaDebugPanel /> instead of a hand-made debug overlay or QA query parsing; ask the user the questions xenia_get_journey returns for it (where it runs, wait for all or show first) before writing it. Finish with a type-check/build and xenia_verify. Stop to ask only for the token choice, the CMS page questions, a production confirmation, or whether analytics needs consent when the site has no banner. Relay every warning from xenia_get_journey to the user: those are dashboard fixes (e.g. an A/B split that isn't sticky), not code changes.`});return vz(t,e),_z(t,e),$z(t,e),t}import{mkdir as Z6,readFile as M6,writeFile as kz}from"node:fs/promises";import{homedir as o_}from"node:os";import{dirname as L6,join as yo}from"node:path";import{fileURLToPath as V6}from"node:url";var a_={"claude-code":{id:"claude-code",displayName:"Claude Code",path:e=>yo(e,".mcp.json"),scope:"project",format:"json",serverKey:["mcpServers"]},cursor:{id:"cursor",displayName:"Cursor",path:e=>yo(e,".cursor","mcp.json"),scope:"project",format:"json",serverKey:["mcpServers"]},windsurf:{id:"windsurf",displayName:"Windsurf",path:()=>yo(o_(),".codeium","windsurf","mcp_config.json"),scope:"user",format:"json",serverKey:["mcpServers"]},copilot:{id:"copilot",displayName:"GitHub Copilot (VS Code)",path:e=>yo(e,".vscode","mcp.json"),scope:"project",format:"json",serverKey:["servers"]},codex:{id:"codex",displayName:"OpenAI Codex CLI",path:()=>yo(o_(),".codex","config.toml"),scope:"user",format:"toml",serverKey:["mcp_servers"]},gemini:{id:"gemini",displayName:"Gemini CLI",path:()=>yo(o_(),".gemini","settings.json"),scope:"user",format:"json",serverKey:["mcpServers"]}};async function xz(e){let t=s_(e,"--client"),n=s_(e,"--project")??process.cwd(),i=s_(e,"--base-url"),r=e.includes("--local");if(!t||!Object.hasOwn(a_,t)){process.stderr.write(`Specify a client: --client <${Object.keys(a_).join("|")}>
|
|
163
163
|
`),process.exit(1);return}let o=a_[t],a=o.path(n),s=F6(o,i,r);if(await Z6(L6(a),{recursive:!0}),(o.format==="toml"?await K6(a,o,s):await q6(a,o,s))==="already-configured"){process.stdout.write(`Xenia is already configured for ${o.displayName} in ${a} \u2014 left unchanged.
|
|
164
164
|
`);return}process.stdout.write([`Configured ${o.displayName}.`,` ${a}${o.scope==="user"?" (applies to all projects)":""}`,"",`Restart ${o.displayName}, then ask it to "connect my Xenia account".`,""].join(`
|
|
165
165
|
`))}function F6(e,t,n){let i={XENIA_CLIENT_NAME:e.displayName};if(t&&(i.XENIA_BASE_URL=t),n){let r=V6(new URL("./bin.js",import.meta.url));return{command:process.execPath,args:[r],env:i}}return{command:"npx",args:["-y","@xenia-martech/mcp"],env:i}}async function q6(e,t,n){let i=await J6(e)??{},r=t.serverKey[0]??"mcpServers",o=wz(i[r])?i[r]:{};return o.xenia=n,i[r]=o,await kz(e,`${JSON.stringify(i,null,2)}
|
package/package.json
CHANGED