@12-apps/mcp 3.5.0 → 3.6.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/ADOPTING.md +69 -1
- package/dist/chunk-FBUSSQSK.js +22 -0
- package/dist/chunk-FBUSSQSK.js.map +1 -0
- package/dist/{chunk-FYEVBTDU.js → chunk-HRAQKMDC.js} +12 -20
- package/dist/chunk-HRAQKMDC.js.map +1 -0
- package/dist/{guide-DV5MQbCg.d.ts → guide-KQNcXlMG.d.ts} +32 -17
- package/dist/index.d.ts +2 -1
- package/dist/index.js +11 -7
- package/dist/index.js.map +1 -1
- package/dist/oauth/index.d.ts +1 -1
- package/dist/oauth/index.js +1 -1
- package/dist/pt-BR-e1RnV2v8.d.ts +25 -0
- package/dist/react/index.d.ts +197 -30
- package/dist/react/index.js +327 -147
- package/dist/react/index.js.map +1 -1
- package/package.json +6 -6
- package/src/guide.ts +33 -165
- package/src/index.ts +8 -3
- package/src/pt-BR.ts +195 -0
- package/src/react/ai-capabilities.tsx +10 -6
- package/src/react/ai-connection-utils.ts +18 -13
- package/src/react/ai-flow-steps.tsx +63 -43
- package/src/react/ai-landing.tsx +47 -21
- package/src/react/ai-onboarding.tsx +30 -25
- package/src/react/ai-status-board.tsx +18 -11
- package/src/react/ai-steps.tsx +60 -23
- package/src/react/copy.ts +154 -0
- package/src/react/host-connect-guide.tsx +24 -8
- package/src/react/host-select-step.tsx +4 -1
- package/src/react/index.ts +21 -3
- package/src/react/pt-BR.ts +109 -0
- package/dist/chunk-FYEVBTDU.js.map +0 -1
package/src/guide.ts
CHANGED
|
@@ -87,138 +87,6 @@ export interface AiHostGuide {
|
|
|
87
87
|
pluginUrl?: string;
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
const CONNECTOR_TAIL: readonly string[] = [
|
|
91
|
-
"Deixe OAuth Client ID e Client Secret em branco — não é preciso gerar credenciais: a loja registra o conector automaticamente no primeiro acesso.",
|
|
92
|
-
"Confirme e clique em Connect: abre a tela de login da loja — entre com a SUA conta de lojista e autorize o acesso.",
|
|
93
|
-
"Pronto: ative o conector na conversa para o assistente consultar e operar a sua loja.",
|
|
94
|
-
];
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* ChatGPT's two-stage configuration (Developer mode is now required before a
|
|
98
|
-
* connector can be created). Stage 1 enables Developer mode in Security & login;
|
|
99
|
-
* stage 2 creates the connector and signs in — which registers the connection on
|
|
100
|
-
* the store side, so no prompt needs to be pasted afterwards.
|
|
101
|
-
*/
|
|
102
|
-
function chatgptConfigureStages(
|
|
103
|
-
platformName: string,
|
|
104
|
-
): readonly AiHostConfigureStage[] {
|
|
105
|
-
return [
|
|
106
|
-
{
|
|
107
|
-
id: "enable-dev-mode",
|
|
108
|
-
label: "enable developer mode",
|
|
109
|
-
link: {
|
|
110
|
-
url: "https://chatgpt.com/plugins#settings/Security",
|
|
111
|
-
label: "Abrir Segurança e login",
|
|
112
|
-
},
|
|
113
|
-
steps: [
|
|
114
|
-
"Ative o Modo desenvolvedor em Settings › Security and login (Segurança e login).",
|
|
115
|
-
],
|
|
116
|
-
},
|
|
117
|
-
{
|
|
118
|
-
id: "configurar",
|
|
119
|
-
label: "configurar",
|
|
120
|
-
link: {
|
|
121
|
-
url: "https://chatgpt.com/plugins#settings/Connectors?create-connector=true&redirectAfter=%2Fplugins",
|
|
122
|
-
label: "Criar o conector",
|
|
123
|
-
},
|
|
124
|
-
steps: [
|
|
125
|
-
"Isso vai abrir um popup para você criar um plugin novo. Coloque como nome o nome da sua loja e, no campo MCP, o link copiado no passo anterior.",
|
|
126
|
-
'Marque a caixa "I understand and want to continue" — a OpenAI não revisou este servidor MCP; ela avisa que sites podem tentar roubar seus dados ou induzir o modelo a ações indevidas, incluindo destruir dados.',
|
|
127
|
-
`Clique em "Sign in with ${platformName}" e entre com a sua conta de lojista para autorizar o acesso. Pronto: a conexão é registrada automaticamente.`,
|
|
128
|
-
],
|
|
129
|
-
},
|
|
130
|
-
];
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* The AI hosts a store owner can connect, in recommended order. Same OAuth flow
|
|
135
|
-
* everywhere (the host drives it) — only the menu path differs per app.
|
|
136
|
-
*
|
|
137
|
-
* A FUNCTION of the platform's name, because one step is not generic: the
|
|
138
|
-
* ChatGPT connector's consent screen shows an OAuth button labelled with
|
|
139
|
-
* whoever operates the server, and the owner is told which button to click. It
|
|
140
|
-
* used to name one particular STORE on one particular deployment — not even the
|
|
141
|
-
* product, a tenant of it — so every other adopter instructed its owners to
|
|
142
|
-
* click a button that does not exist.
|
|
143
|
-
*/
|
|
144
|
-
export function aiHostGuides(platformName: string): readonly AiHostGuide[] {
|
|
145
|
-
const chatgptStages = chatgptConfigureStages(platformName);
|
|
146
|
-
return [
|
|
147
|
-
{
|
|
148
|
-
id: "claude",
|
|
149
|
-
label: "Claude.ai",
|
|
150
|
-
brand: "claude",
|
|
151
|
-
kind: "No navegador",
|
|
152
|
-
link: {
|
|
153
|
-
url: "https://claude.ai/new?modal=add-custom-connector#settings/customize-connectors",
|
|
154
|
-
label: "Abrir os conectores do Claude",
|
|
155
|
-
},
|
|
156
|
-
docs: {
|
|
157
|
-
url: "https://support.anthropic.com/en/articles/11175166-how-do-i-connect-mcp-servers-to-claude-ai",
|
|
158
|
-
label: "documentação oficial da Anthropic — conectores personalizados",
|
|
159
|
-
},
|
|
160
|
-
steps: [
|
|
161
|
-
"Clique no botão acima (ou vá em Settings › Customize › Connectors) e escolha Add custom connector.",
|
|
162
|
-
"Dê um nome ao conector (ex.: o nome da sua loja) e cole a URL do servidor MCP da sua loja (copie acima) no campo de URL.",
|
|
163
|
-
...CONNECTOR_TAIL,
|
|
164
|
-
],
|
|
165
|
-
},
|
|
166
|
-
{
|
|
167
|
-
id: "claude-desktop",
|
|
168
|
-
label: "Claude Desktop",
|
|
169
|
-
brand: "claude",
|
|
170
|
-
kind: "Aplicativo (Windows/Mac)",
|
|
171
|
-
docs: {
|
|
172
|
-
url: "https://support.anthropic.com/en/articles/11175166-how-do-i-connect-mcp-servers-to-claude-ai",
|
|
173
|
-
label: "documentação oficial da Anthropic — conectores personalizados",
|
|
174
|
-
},
|
|
175
|
-
steps: [
|
|
176
|
-
"Abra o Claude Desktop e vá em Settings (⚙️) › Connectors.",
|
|
177
|
-
"Clique em Add custom connector e cole a URL do servidor MCP da sua loja (copie acima).",
|
|
178
|
-
...CONNECTOR_TAIL,
|
|
179
|
-
],
|
|
180
|
-
},
|
|
181
|
-
{
|
|
182
|
-
id: "chatgpt",
|
|
183
|
-
label: "ChatGPT",
|
|
184
|
-
brand: "openai",
|
|
185
|
-
kind: "No navegador",
|
|
186
|
-
link: {
|
|
187
|
-
url: "https://chatgpt.com/plugins",
|
|
188
|
-
label: "Abrir os plugins do ChatGPT",
|
|
189
|
-
},
|
|
190
|
-
docs: {
|
|
191
|
-
url: "https://developers.openai.com/apps-sdk/deploy/connect-chatgpt",
|
|
192
|
-
label:
|
|
193
|
-
"documentação oficial da OpenAI — conectar um servidor MCP ao ChatGPT",
|
|
194
|
-
},
|
|
195
|
-
configureStages: chatgptStages,
|
|
196
|
-
// Mirrors the flattened stage instructions so the MCP connect guide
|
|
197
|
-
// (`connectToChatGpt`) can never drift from what owners see in the wizard.
|
|
198
|
-
steps: chatgptStages.flatMap((stage) => stage.steps),
|
|
199
|
-
},
|
|
200
|
-
{
|
|
201
|
-
id: "codex",
|
|
202
|
-
label: "Codex",
|
|
203
|
-
brand: "openai",
|
|
204
|
-
kind: "App / CLI de desenvolvedor",
|
|
205
|
-
link: {
|
|
206
|
-
url: "https://developers.openai.com/codex",
|
|
207
|
-
label: "Documentação do Codex",
|
|
208
|
-
},
|
|
209
|
-
docs: {
|
|
210
|
-
url: "https://developers.openai.com/apps-sdk/deploy/connect-chatgpt",
|
|
211
|
-
label: "documentação oficial da OpenAI — conectar um servidor MCP",
|
|
212
|
-
},
|
|
213
|
-
steps: [
|
|
214
|
-
"No Codex, abra as configurações de MCP (Settings › MCP no app, ou o arquivo de configuração na CLI).",
|
|
215
|
-
"Adicione um servidor MCP e cole a URL do servidor MCP da sua loja (copie acima) como um conector remoto (HTTP).",
|
|
216
|
-
...CONNECTOR_TAIL,
|
|
217
|
-
],
|
|
218
|
-
},
|
|
219
|
-
];
|
|
220
|
-
}
|
|
221
|
-
|
|
222
90
|
export interface AiCapability {
|
|
223
91
|
/** Stable id — maps to an icon in the component. */
|
|
224
92
|
id: string;
|
|
@@ -228,38 +96,16 @@ export interface AiCapability {
|
|
|
228
96
|
detail: string;
|
|
229
97
|
}
|
|
230
98
|
|
|
231
|
-
/** What a connected assistant does for the owner — one marketing card each. */
|
|
232
|
-
export const AI_CAPABILITIES: readonly AiCapability[] = [
|
|
233
|
-
{
|
|
234
|
-
id: "orders",
|
|
235
|
-
title: "Acompanhe seus pedidos",
|
|
236
|
-
detail: '"Quais pedidos entraram hoje?"',
|
|
237
|
-
},
|
|
238
|
-
{
|
|
239
|
-
id: "inventory",
|
|
240
|
-
title: "Controle o estoque",
|
|
241
|
-
detail:
|
|
242
|
-
'"Quanto ainda tenho do produto X? Registre a entrada de 20 unidades."',
|
|
243
|
-
},
|
|
244
|
-
{
|
|
245
|
-
id: "catalog",
|
|
246
|
-
title: "Gerencie o catálogo",
|
|
247
|
-
detail: "Crie e edite produtos e categorias conversando.",
|
|
248
|
-
},
|
|
249
|
-
{
|
|
250
|
-
id: "sales",
|
|
251
|
-
title: "Entenda suas vendas",
|
|
252
|
-
detail: '"Qual foi o faturamento da semana?"',
|
|
253
|
-
},
|
|
254
|
-
];
|
|
255
99
|
|
|
256
100
|
/**
|
|
257
101
|
* The permission model in one line, shown prominently: the assistant acts AS
|
|
258
102
|
* the signed-in owner (auth-passthrough) — it can do exactly what the owner
|
|
259
103
|
* can, nothing more, and no extra credential/API key is ever created.
|
|
104
|
+
*
|
|
105
|
+
* A TYPE now, not a constant. The sentence is copy, and a package that shipped
|
|
106
|
+
* it made one product's Portuguese every adopter's silent default.
|
|
260
107
|
*/
|
|
261
|
-
export
|
|
262
|
-
"O assistente age em seu nome, com exatamente as suas permissões: ele pode fazer o que você pode fazer na sua loja — nada além disso. Não é preciso criar nenhuma chave ou credencial extra; a autorização usa o seu próprio login.";
|
|
108
|
+
export type AiPermissionModel = string;
|
|
263
109
|
|
|
264
110
|
/** The two tools the paste-in prompt drives, and what to call the store id. */
|
|
265
111
|
export interface AiConnectPromptSpec {
|
|
@@ -288,12 +134,34 @@ export interface AiConnectPromptSpec {
|
|
|
288
134
|
* two tools that do not exist, and because nothing registered the connection,
|
|
289
135
|
* the wizard's confirm step then waited forever for a state that could never
|
|
290
136
|
* arrive.
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* The sentences the paste-in prompt is written in.
|
|
140
|
+
*
|
|
141
|
+
* A template rather than a string, because the prompt INTERPOLATES the host's
|
|
142
|
+
* own tool names and its word order is language-specific. The package supplies
|
|
143
|
+
* the spec; the host supplies the way it is said.
|
|
144
|
+
*/
|
|
145
|
+
export interface AiConnectPromptCopy {
|
|
146
|
+
(spec: AiConnectPromptSpec): string;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* The message the owner pastes into the assistant's chat right after
|
|
151
|
+
* connecting: announce the connection, then read something real to prove it
|
|
152
|
+
* works. The owner types nothing.
|
|
153
|
+
*
|
|
154
|
+
* BUILT from the host's tool names rather than shipped with them. This was a
|
|
155
|
+
* constant naming two tools — `announceAiConnection` and `listInventory` — that
|
|
156
|
+
* THIS PACKAGE does not define or serve; they belong to one adopter's surface.
|
|
157
|
+
* Any other host handed its owner a prompt instructing the assistant to call
|
|
158
|
+
* two tools that do not exist, and because nothing registered the connection,
|
|
159
|
+
* the wizard's confirm step then waited forever for a state that could never
|
|
160
|
+
* arrive.
|
|
161
|
+
*
|
|
162
|
+
* The WORDS around those names are the host's too, since FUT-760: this is a
|
|
163
|
+
* thin seam that hands the spec to the host's own template.
|
|
291
164
|
*/
|
|
292
|
-
export function aiConnectPrompt(spec: AiConnectPromptSpec): string {
|
|
293
|
-
return (
|
|
294
|
-
"Você agora tem acesso ao conector MCP da minha loja. Faça, nesta ordem:\n" +
|
|
295
|
-
`1) Execute a ferramenta ${spec.announceTool} informando qual assistente você é (host: "chatgpt", "claude" ou "codex") para registrar a conexão com a minha loja.\n` +
|
|
296
|
-
`2) Execute a ferramenta ${spec.probeTool} para confirmar o acesso a ${spec.probeSubject}.\n` +
|
|
297
|
-
`Se precisar do identificador da loja, me pergunte o ${spec.identifierName}.`
|
|
298
|
-
);
|
|
165
|
+
export function aiConnectPrompt(spec: AiConnectPromptSpec, copy: AiConnectPromptCopy): string {
|
|
166
|
+
return copy(spec);
|
|
299
167
|
}
|
package/src/index.ts
CHANGED
|
@@ -13,9 +13,6 @@ export * from "./types";
|
|
|
13
13
|
// truth for BOTH the `@12-apps/mcp/react` onboarding UI and the server-side connect
|
|
14
14
|
// tools, so what an agent reads via MCP cannot drift from what owners see.
|
|
15
15
|
export {
|
|
16
|
-
aiHostGuides,
|
|
17
|
-
AI_CAPABILITIES,
|
|
18
|
-
AI_PERMISSION_MODEL,
|
|
19
16
|
aiConnectPrompt,
|
|
20
17
|
type AiConnectPromptSpec,
|
|
21
18
|
providerForHostId,
|
|
@@ -99,3 +96,11 @@ export {
|
|
|
99
96
|
type AuthorizationServerMetadataInput,
|
|
100
97
|
type AuthorizationServerPaths,
|
|
101
98
|
} from "./auth/authorization-server-metadata";
|
|
99
|
+
|
|
100
|
+
export type { AiConnectPromptCopy } from "./guide";
|
|
101
|
+
export {
|
|
102
|
+
PT_BR_AI_CAPABILITIES,
|
|
103
|
+
PT_BR_AI_CONNECT_PROMPT,
|
|
104
|
+
PT_BR_AI_HOST_GUIDES,
|
|
105
|
+
PT_BR_AI_PERMISSION_MODEL,
|
|
106
|
+
} from "./pt-BR";
|
package/src/pt-BR.ts
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AiCapability,
|
|
3
|
+
AiConnectPromptSpec,
|
|
4
|
+
AiHostConfigureStage,
|
|
5
|
+
AiHostGuide,
|
|
6
|
+
AiPermissionModel,
|
|
7
|
+
} from "./guide";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The pt-BR pack for the AI-integration surface — NAMED constants a host passes
|
|
11
|
+
* by hand, never defaults (FUT-760).
|
|
12
|
+
*
|
|
13
|
+
* The filename is what exempts this file from the copy-portability gate:
|
|
14
|
+
* Portuguese may ship, it may not be silent. Every sentence here is VERBATIM
|
|
15
|
+
* what `guide.ts` used to compile in, so a host adopting it sees no change on
|
|
16
|
+
* screen — what changes is that the walkthrough is chosen in a diff.
|
|
17
|
+
*
|
|
18
|
+
* The guides are DATA as much as copy: which assistants are offered, their
|
|
19
|
+
* stage ids and brands. Both halves travel together because a step label and
|
|
20
|
+
* the stage it labels are useless apart.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
const CONNECTOR_TAIL: readonly string[] = [
|
|
24
|
+
"Deixe OAuth Client ID e Client Secret em branco — não é preciso gerar credenciais: a loja registra o conector automaticamente no primeiro acesso.",
|
|
25
|
+
"Confirme e clique em Connect: abre a tela de login da loja — entre com a SUA conta de lojista e autorize o acesso.",
|
|
26
|
+
"Pronto: ative o conector na conversa para o assistente consultar e operar a sua loja.",
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* ChatGPT's two-stage configuration (Developer mode is now required before a
|
|
31
|
+
* connector can be created). Stage 1 enables Developer mode in Security & login;
|
|
32
|
+
* stage 2 creates the connector and signs in — which registers the connection on
|
|
33
|
+
* the store side, so no prompt needs to be pasted afterwards.
|
|
34
|
+
*/
|
|
35
|
+
function chatgptConfigureStages(
|
|
36
|
+
platformName: string,
|
|
37
|
+
): readonly AiHostConfigureStage[] {
|
|
38
|
+
return [
|
|
39
|
+
{
|
|
40
|
+
id: "enable-dev-mode",
|
|
41
|
+
label: "enable developer mode",
|
|
42
|
+
link: {
|
|
43
|
+
url: "https://chatgpt.com/plugins#settings/Security",
|
|
44
|
+
label: "Abrir Segurança e login",
|
|
45
|
+
},
|
|
46
|
+
steps: [
|
|
47
|
+
"Ative o Modo desenvolvedor em Settings › Security and login (Segurança e login).",
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
id: "configurar",
|
|
52
|
+
label: "configurar",
|
|
53
|
+
link: {
|
|
54
|
+
url: "https://chatgpt.com/plugins#settings/Connectors?create-connector=true&redirectAfter=%2Fplugins",
|
|
55
|
+
label: "Criar o conector",
|
|
56
|
+
},
|
|
57
|
+
steps: [
|
|
58
|
+
"Isso vai abrir um popup para você criar um plugin novo. Coloque como nome o nome da sua loja e, no campo MCP, o link copiado no passo anterior.",
|
|
59
|
+
'Marque a caixa "I understand and want to continue" — a OpenAI não revisou este servidor MCP; ela avisa que sites podem tentar roubar seus dados ou induzir o modelo a ações indevidas, incluindo destruir dados.',
|
|
60
|
+
`Clique em "Sign in with ${platformName}" e entre com a sua conta de lojista para autorizar o acesso. Pronto: a conexão é registrada automaticamente.`,
|
|
61
|
+
],
|
|
62
|
+
},
|
|
63
|
+
];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* The AI hosts a store owner can connect, in recommended order. Same OAuth flow
|
|
68
|
+
* everywhere (the host drives it) — only the menu path differs per app.
|
|
69
|
+
*
|
|
70
|
+
* A FUNCTION of the platform's name, because one step is not generic: the
|
|
71
|
+
* ChatGPT connector's consent screen shows an OAuth button labelled with
|
|
72
|
+
* whoever operates the server, and the owner is told which button to click. It
|
|
73
|
+
* used to name one particular STORE on one particular deployment — not even the
|
|
74
|
+
* product, a tenant of it — so every other adopter instructed its owners to
|
|
75
|
+
* click a button that does not exist.
|
|
76
|
+
*/
|
|
77
|
+
export function PT_BR_AI_HOST_GUIDES(platformName: string): readonly AiHostGuide[] {
|
|
78
|
+
const chatgptStages = chatgptConfigureStages(platformName);
|
|
79
|
+
return [
|
|
80
|
+
{
|
|
81
|
+
id: "claude",
|
|
82
|
+
label: "Claude.ai",
|
|
83
|
+
brand: "claude",
|
|
84
|
+
kind: "No navegador",
|
|
85
|
+
link: {
|
|
86
|
+
url: "https://claude.ai/new?modal=add-custom-connector#settings/customize-connectors",
|
|
87
|
+
label: "Abrir os conectores do Claude",
|
|
88
|
+
},
|
|
89
|
+
docs: {
|
|
90
|
+
url: "https://support.anthropic.com/en/articles/11175166-how-do-i-connect-mcp-servers-to-claude-ai",
|
|
91
|
+
label: "documentação oficial da Anthropic — conectores personalizados",
|
|
92
|
+
},
|
|
93
|
+
steps: [
|
|
94
|
+
"Clique no botão acima (ou vá em Settings › Customize › Connectors) e escolha Add custom connector.",
|
|
95
|
+
"Dê um nome ao conector (ex.: o nome da sua loja) e cole a URL do servidor MCP da sua loja (copie acima) no campo de URL.",
|
|
96
|
+
...CONNECTOR_TAIL,
|
|
97
|
+
],
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
id: "claude-desktop",
|
|
101
|
+
label: "Claude Desktop",
|
|
102
|
+
brand: "claude",
|
|
103
|
+
kind: "Aplicativo (Windows/Mac)",
|
|
104
|
+
docs: {
|
|
105
|
+
url: "https://support.anthropic.com/en/articles/11175166-how-do-i-connect-mcp-servers-to-claude-ai",
|
|
106
|
+
label: "documentação oficial da Anthropic — conectores personalizados",
|
|
107
|
+
},
|
|
108
|
+
steps: [
|
|
109
|
+
"Abra o Claude Desktop e vá em Settings (⚙️) › Connectors.",
|
|
110
|
+
"Clique em Add custom connector e cole a URL do servidor MCP da sua loja (copie acima).",
|
|
111
|
+
...CONNECTOR_TAIL,
|
|
112
|
+
],
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
id: "chatgpt",
|
|
116
|
+
label: "ChatGPT",
|
|
117
|
+
brand: "openai",
|
|
118
|
+
kind: "No navegador",
|
|
119
|
+
link: {
|
|
120
|
+
url: "https://chatgpt.com/plugins",
|
|
121
|
+
label: "Abrir os plugins do ChatGPT",
|
|
122
|
+
},
|
|
123
|
+
docs: {
|
|
124
|
+
url: "https://developers.openai.com/apps-sdk/deploy/connect-chatgpt",
|
|
125
|
+
label:
|
|
126
|
+
"documentação oficial da OpenAI — conectar um servidor MCP ao ChatGPT",
|
|
127
|
+
},
|
|
128
|
+
configureStages: chatgptStages,
|
|
129
|
+
// Mirrors the flattened stage instructions so the MCP connect guide
|
|
130
|
+
// (`connectToChatGpt`) can never drift from what owners see in the wizard.
|
|
131
|
+
steps: chatgptStages.flatMap((stage) => stage.steps),
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
id: "codex",
|
|
135
|
+
label: "Codex",
|
|
136
|
+
brand: "openai",
|
|
137
|
+
kind: "App / CLI de desenvolvedor",
|
|
138
|
+
link: {
|
|
139
|
+
url: "https://developers.openai.com/codex",
|
|
140
|
+
label: "Documentação do Codex",
|
|
141
|
+
},
|
|
142
|
+
docs: {
|
|
143
|
+
url: "https://developers.openai.com/apps-sdk/deploy/connect-chatgpt",
|
|
144
|
+
label: "documentação oficial da OpenAI — conectar um servidor MCP",
|
|
145
|
+
},
|
|
146
|
+
steps: [
|
|
147
|
+
"No Codex, abra as configurações de MCP (Settings › MCP no app, ou o arquivo de configuração na CLI).",
|
|
148
|
+
"Adicione um servidor MCP e cole a URL do servidor MCP da sua loja (copie acima) como um conector remoto (HTTP).",
|
|
149
|
+
...CONNECTOR_TAIL,
|
|
150
|
+
],
|
|
151
|
+
},
|
|
152
|
+
];
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export const PT_BR_AI_CAPABILITIES: readonly AiCapability[] = [
|
|
156
|
+
{
|
|
157
|
+
id: "orders",
|
|
158
|
+
title: "Acompanhe seus pedidos",
|
|
159
|
+
detail: '"Quais pedidos entraram hoje?"',
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
id: "inventory",
|
|
163
|
+
title: "Controle o estoque",
|
|
164
|
+
detail:
|
|
165
|
+
'"Quanto ainda tenho do produto X? Registre a entrada de 20 unidades."',
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
id: "catalog",
|
|
169
|
+
title: "Gerencie o catálogo",
|
|
170
|
+
detail: "Crie e edite produtos e categorias conversando.",
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
id: "sales",
|
|
174
|
+
title: "Entenda suas vendas",
|
|
175
|
+
detail: '"Qual foi o faturamento da semana?"',
|
|
176
|
+
},
|
|
177
|
+
];
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* The permission model in one line, shown prominently: the assistant acts AS
|
|
181
|
+
* the signed-in owner (auth-passthrough) — it can do exactly what the owner
|
|
182
|
+
* can, nothing more, and no extra credential/API key is ever created.
|
|
183
|
+
*/
|
|
184
|
+
export const PT_BR_AI_PERMISSION_MODEL: AiPermissionModel =
|
|
185
|
+
"O assistente age em seu nome, com exatamente as suas permissões: ele pode fazer o que você pode fazer na sua loja — nada além disso. Não é preciso criar nenhuma chave ou credencial extra; a autorização usa o seu próprio login.";
|
|
186
|
+
|
|
187
|
+
/** The pt-BR paste-in prompt, built from the host's own tool names. */
|
|
188
|
+
export function PT_BR_AI_CONNECT_PROMPT(spec: AiConnectPromptSpec): string {
|
|
189
|
+
return (
|
|
190
|
+
"Você agora tem acesso ao conector MCP da minha loja. Faça, nesta ordem:\n" +
|
|
191
|
+
`1) Execute a ferramenta ${spec.announceTool} informando qual assistente você é (host: "chatgpt", "claude" ou "codex") para registrar a conexão com a minha loja.\n` +
|
|
192
|
+
`2) Execute a ferramenta ${spec.probeTool} para confirmar o acesso a ${spec.probeSubject}.\n` +
|
|
193
|
+
`Se precisar do identificador da loja, me pergunte o ${spec.identifierName}.`
|
|
194
|
+
);
|
|
195
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Box } from "@12-apps/ui/mui/Box";
|
|
2
2
|
import { Text } from "@12-apps/ui/typography/Text";
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import type { AiCapability } from "../guide";
|
|
5
|
+
import type { AiCapabilitiesCopy } from "./copy";
|
|
5
6
|
import { CapabilityIcon } from "./ai-icons";
|
|
6
7
|
|
|
7
8
|
/** One marketing card: an icon, a headline and an example prompt (as a bubble). */
|
|
@@ -64,22 +65,25 @@ function CapabilityCard({ capability }: { capability: AiCapability }): React.JSX
|
|
|
64
65
|
* Marketing block for the AI integration: a headline + a responsive grid of
|
|
65
66
|
* capability cards. Shown on the onboarding landing (before the owner starts) to
|
|
66
67
|
* sell the feature — "here's what the assistant does for you". `capabilities`
|
|
67
|
-
*
|
|
68
|
+
* and `copy` are REQUIRED host copy — the package ships no default sentence
|
|
69
|
+
* (FUT-760).
|
|
68
70
|
*/
|
|
69
71
|
export function AiCapabilities({
|
|
70
|
-
capabilities
|
|
72
|
+
capabilities,
|
|
73
|
+
copy,
|
|
71
74
|
}: {
|
|
72
|
-
capabilities
|
|
75
|
+
capabilities: readonly AiCapability[];
|
|
76
|
+
copy: AiCapabilitiesCopy;
|
|
73
77
|
}): React.JSX.Element {
|
|
74
78
|
return (
|
|
75
79
|
<Box data-testid="ai-capability-examples" sx={{ width: "100%" }}>
|
|
76
80
|
<Box sx={{ mb: 3 }}>
|
|
77
81
|
<Text variant="heading" size="sm" as="h2">
|
|
78
|
-
|
|
82
|
+
{copy.heading}
|
|
79
83
|
</Text>
|
|
80
84
|
<Box sx={{ mt: 0.5 }}>
|
|
81
85
|
<Text variant="body" size="sm" as="p" color="secondary">
|
|
82
|
-
|
|
86
|
+
{copy.subheading}
|
|
83
87
|
</Text>
|
|
84
88
|
</Box>
|
|
85
89
|
</Box>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { AiConnectionSummaryCopy } from "./copy";
|
|
1
2
|
import { providerForHostId, type AiHostGuide, type AiProvider } from "../guide";
|
|
2
3
|
|
|
3
4
|
/**
|
|
@@ -54,14 +55,14 @@ export function connectionForHost(
|
|
|
54
55
|
);
|
|
55
56
|
}
|
|
56
57
|
|
|
57
|
-
/**
|
|
58
|
-
export function activeAgo(date: Date): string {
|
|
58
|
+
/** The recency line from a timestamp, in the host's own words. */
|
|
59
|
+
export function activeAgo(date: Date, copy: AiConnectionSummaryCopy): string {
|
|
59
60
|
const minutes = Math.max(0, Math.floor((Date.now() - date.getTime()) / 60_000));
|
|
60
|
-
if (minutes < 1) return
|
|
61
|
-
if (minutes < 60) return
|
|
61
|
+
if (minutes < 1) return copy.activeNow;
|
|
62
|
+
if (minutes < 60) return copy.activeMinutes(minutes);
|
|
62
63
|
const hours = Math.floor(minutes / 60);
|
|
63
|
-
if (hours < 24) return
|
|
64
|
-
return
|
|
64
|
+
if (hours < 24) return copy.activeHours(hours);
|
|
65
|
+
return copy.activeDays(Math.floor(hours / 24));
|
|
65
66
|
}
|
|
66
67
|
|
|
67
68
|
/** The most-recently-active connection across all providers (null when none). */
|
|
@@ -77,20 +78,24 @@ export function connectedTitle(
|
|
|
77
78
|
connections: readonly AiConnection[],
|
|
78
79
|
hosts: readonly AiHostGuide[],
|
|
79
80
|
connectedHostId: string | undefined,
|
|
81
|
+
copy: AiConnectionSummaryCopy,
|
|
80
82
|
): string {
|
|
81
83
|
const providers = [...new Set(connections.map((c) => c.host).filter((h): h is AiProvider => h !== null))];
|
|
82
|
-
if (providers.length === 1) return `${PROVIDER_LABEL[providers[0]!]}
|
|
84
|
+
if (providers.length === 1) return `${PROVIDER_LABEL[providers[0]!]} ${copy.connectedSuffix}`;
|
|
83
85
|
if (providers.length > 1) {
|
|
84
|
-
return
|
|
86
|
+
return copy.connectedSeveral(providers.map((p) => PROVIDER_LABEL[p]).join(", "));
|
|
85
87
|
}
|
|
86
88
|
// Legacy connection with no attributed provider — name the completed host.
|
|
87
|
-
if (connections.length > 0) return `${hostLabel(hosts, connectedHostId)}
|
|
88
|
-
return
|
|
89
|
+
if (connections.length > 0) return `${hostLabel(hosts, connectedHostId)} ${copy.connectedSuffix}`;
|
|
90
|
+
return copy.connectedGeneric;
|
|
89
91
|
}
|
|
90
92
|
|
|
91
93
|
/** The completed summary line (second line) for the configured-state header. */
|
|
92
|
-
export function connectedSummary(
|
|
94
|
+
export function connectedSummary(
|
|
95
|
+
connections: readonly AiConnection[],
|
|
96
|
+
copy: AiConnectionSummaryCopy,
|
|
97
|
+
): string {
|
|
93
98
|
const recent = mostRecent(connections);
|
|
94
|
-
if (!recent) return
|
|
95
|
-
return activeAgo(recent.lastActiveAt);
|
|
99
|
+
if (!recent) return copy.configured;
|
|
100
|
+
return activeAgo(recent.lastActiveAt, copy);
|
|
96
101
|
}
|