sapiens-mcp 1.45.1 → 1.46.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/README.md +8 -0
- package/dist/prompts.js +2 -2
- package/dist/registry.js +6 -6
- package/dist/skills.js +77 -26
- package/dist/tools/character.js +12 -2
- package/dist/tools/gallery.js +58 -7
- package/dist/tools/image.js +1 -16
- package/dist/tools/profile.js +14 -0
- package/dist/tools/studios.js +46 -39
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -53,6 +53,14 @@ O Claude avisa o custo antes de gastar, e geração que falha é estornada. Publ
|
|
|
53
53
|
|
|
54
54
|
O servidor só conversa com o backend público do Sapiens (Convex). Sua identidade vem sempre do token de login, nunca de parâmetros soltos. Cada conta só mexe no que é dela.
|
|
55
55
|
|
|
56
|
+
## Sobre o Sapiens Sintéticos
|
|
57
|
+
|
|
58
|
+
O Sapiens Sintéticos é um Studio de IA que constrói Studios: ensino modelo de pensamento na Era Sintética pra cada pessoa montar o próprio sistema de criação, com voz e régua próprias. O método se chama Borderless: 5 pilares, 7 deltas e uma sequência de 7 fases pra tirar ideia do papel (Tesão, Cruzamento, Confronto Crítico, Prototipagem, MVP, Validação, Continuidade).
|
|
59
|
+
|
|
60
|
+
Em inglês o projeto assina **Synthetic Sapiens**: an AI studio that builds studios. The missing skill is not using AI, it is inventing the system the AI feeds. That system is a studio of your own, the personal computer of 2026.
|
|
61
|
+
|
|
62
|
+
Site oficial: [sapiensinteticos.com](https://www.sapiensinteticos.com) · Manifesto: [/manifesto](https://www.sapiensinteticos.com/manifesto) · Contexto pra máquina: [/llms.txt](https://www.sapiensinteticos.com/llms.txt)
|
|
63
|
+
|
|
56
64
|
---
|
|
57
65
|
|
|
58
66
|
Feito por [BorderLess](https://sapiensinteticos.com). Licença MIT.
|
package/dist/prompts.js
CHANGED
|
@@ -89,8 +89,8 @@ export const SAPIENS_PROMPTS = [
|
|
|
89
89
|
build: (a) => `Quero uma imagem de: "${a.cena}". Monte o prompt na regra da casa (full-bleed, ` +
|
|
90
90
|
"sujeito oversized 70%+ do frame, sem moldura/margem, sem 'tarot card'). Confira " +
|
|
91
91
|
"modelo e preço com sapiens_image action=models e meu saldo com sapiens_meta " +
|
|
92
|
-
"action=credits; me diga o custo antes de gerar. Se eu
|
|
93
|
-
"
|
|
92
|
+
"action=credits; me diga o custo antes de gerar. Se eu pedir 'na minha marca' ou " +
|
|
93
|
+
"'com fulano', use brandSlug ou influencerId. Depois de gerar, me mostre a url e " +
|
|
94
94
|
"ofereça publicar na galeria (sapiens_gallery action=publish).",
|
|
95
95
|
},
|
|
96
96
|
];
|
package/dist/registry.js
CHANGED
|
@@ -58,7 +58,7 @@ export const TOOLS = {
|
|
|
58
58
|
handler: meta,
|
|
59
59
|
},
|
|
60
60
|
sapiens_skill: {
|
|
61
|
-
description: "As SKILLS da casa: o passo a passo travado de cada fluxo do Sapiens, servido pelo próprio connector (sem login, sem custo, sem rede). LEIA A SKILL ANTES DE OPERAR O FLUXO — é mais barato que errar uma geração que cobra Sinapses. Sub-actions: 'list' (índice: slug + quando usar cada uma), 'get' (o SKILL.md inteiro, passe name=<slug>). Slugs: primeiros-passos (porta de entrada e as 4 armadilhas: timeout que já cobrou, disjuntor anti-loop, saldo, sessão), voz-da-casa (DNA editorial, leia antes de redigir qualquer texto publicável), musica (Musicator em 4 passos + efeito sonoro), video (qual modelo, iterar barato no Mini, storyboard por referência, sonorize), imagem (prompt full-bleed na régua da casa, multi-referência, templates), studio (o perfil de empresa
|
|
61
|
+
description: "As SKILLS da casa: o passo a passo travado de cada fluxo do Sapiens, servido pelo próprio connector (sem login, sem custo, sem rede). LEIA A SKILL ANTES DE OPERAR O FLUXO — é mais barato que errar uma geração que cobra Sinapses. Sub-actions: 'list' (índice: slug + quando usar cada uma), 'get' (o SKILL.md inteiro, passe name=<slug>). Slugs: primeiros-passos (porta de entrada e as 4 armadilhas: timeout que já cobrou, disjuntor anti-loop, saldo, sessão), voz-da-casa (DNA editorial, leia antes de redigir qualquer texto publicável), musica (Musicator em 4 passos + efeito sonoro), video (qual modelo, iterar barato no Mini, storyboard por referência, sonorize), imagem (prompt full-bleed na régua da casa, multi-referência, templates), studio (fundar a casa, o perfil de empresa, o time, e por que o studio não entra na geração), tirinha (2 fases, a imagem sai SEM texto), forum-comunidade (mídia estruturada, menção, tese), companhia (o Sintético veste você), trilhas (missão e prova), minha-soul (instala o retrato do usuário como skill do projeto onde vocês estão). O mesmo conteúdo também sai como resource MCP em skill://sapiens/<slug>/SKILL.md pra quem lê resources.",
|
|
62
62
|
schema: skillSchema,
|
|
63
63
|
handler: skill,
|
|
64
64
|
},
|
|
@@ -68,7 +68,7 @@ export const TOOLS = {
|
|
|
68
68
|
handler: repertorio,
|
|
69
69
|
},
|
|
70
70
|
sapiens_gallery: {
|
|
71
|
-
description: "Browse, publicação e upload das imagens do user. Sub-actions: list (últimas N imagens, com prompt/model/url + isPublic), get (1 imagem com metadados, opcionalmente base64), publish (torna a PRÓPRIA imagem pública: entra na galeria pública + feed Pinterest, e ganha página indexável /imagem/<id> se o modelo não for degen — devolve publicPageUrl), unpublish (volta a privada), upload (traz pra galeria uma peça gerada FORA da casa, por sourceUrl https, filePath local ou base64; ADMIN por ora). Use list/get pra reusar imagem como referência (passe o imageId em sapiens_image mode=edit ou mode=variation) ou pra mostrar pro user o que ele já tem; publish quando o user quer divulgar a imagem dele. IMPORTANTE sobre upload: a peça entra PRIVADA e continua privada — o servidor recusa publicar e recusa compartilhar na comunidade, porque ela é do usuário e a responsabilidade é dele. O caminho pra ela virar coisa pública é usar como referência numa geração daqui e publicar o resultado.",
|
|
71
|
+
description: "Browse, publicação e upload das imagens do user. Sub-actions: list (últimas N imagens, com prompt/model/url + isPublic), get (1 imagem com metadados, opcionalmente base64), publish (torna a PRÓPRIA imagem pública: entra na galeria pública + feed Pinterest, e ganha página indexável /imagem/<id> se o modelo não for degen — devolve publicPageUrl), unpublish (volta a privada), upload (traz pra galeria uma peça gerada FORA da casa, por sourceUrl https, filePath local ou base64; ADMIN por ora), refs (acopla peças da casa como REFERÊNCIA numa peça que já existe, de upload ou de ingest; ADMIN, e só na própria peça). Use list/get pra reusar imagem como referência (passe o imageId em sapiens_image mode=edit ou mode=variation) ou pra mostrar pro user o que ele já tem; publish quando o user quer divulgar a imagem dele. IMPORTANTE sobre upload: a peça entra PRIVADA e continua privada — o servidor recusa publicar e recusa compartilhar na comunidade, porque ela é do usuário e a responsabilidade é dele. O caminho pra ela virar coisa pública é usar como referência numa geração daqui e publicar o resultado. O refs escreve só proveniência (de que ficha/folha a peça nasceu): não promove nada, e um upload continua sem publicar depois de ganhar referência.",
|
|
72
72
|
schema: gallerySchema,
|
|
73
73
|
handler: gallery,
|
|
74
74
|
},
|
|
@@ -98,7 +98,7 @@ export const TOOLS = {
|
|
|
98
98
|
handler: search,
|
|
99
99
|
},
|
|
100
100
|
sapiens_studios: {
|
|
101
|
-
description: "
|
|
101
|
+
description: "O SEU studio (o perfil de EMPRESA da casa do user) + o catálogo dos estúdios/experimentos Sapiens. Sub-actions: mine (o studio do user: nome/endereço público/marca/operador/tamanho do time), create (FUNDA um studio novo, exige name; nasce privado, de graça, teto de 4 por pessoa), list (catálogo com URL+status+tags+mcpReady), get (detalhe de 1 slug), publishable_url (formata URL /articles/<slug>). Use quando user pergunta 'que estúdios existem', 'qual o meu studio', ou diz 'quero abrir/fundar meu studio', 'criar a página da minha empresa'. Estúdios cobertos: helen-voice, musicator, persona-sapiens, personagem-atlas, sapiens-shorts, sapiens-video, text-post-builder, comic-builder, carrosel-editorial, comunidade, repertorio.",
|
|
102
102
|
schema: studiosSchema,
|
|
103
103
|
handler: studios,
|
|
104
104
|
},
|
|
@@ -143,12 +143,12 @@ export const TOOLS = {
|
|
|
143
143
|
handler: brand,
|
|
144
144
|
},
|
|
145
145
|
sapiens_character: {
|
|
146
|
-
description: "Personagens (character sheets) do Sapiens — a tabela `influencers`: personagem reutilizável com imagens (pra character-lock em geração) + alma (systemPrompt), tudo amarrado à conta do dono do token (sem admin). Sub-actions: list_public (catálogo global de personagens públicos do Explorar; cada um traz mainImageUrl/imageUrls usáveis direto como referenceImageUrls em sapiens_image; sem custo, sem login), get (detalhe de 1 por characterId — público+ativo qualquer um vê, draft/privado só o dono; systemPrompt só volta pro dono), list_mine (os personagens do próprio user, inclui drafts/privados), create (cria rascunho na conta: name + gender + opcional title/systemPrompt), add_image (adiciona imagem ao próprio personagem via imageUrl público OU sourceImageId da galeria; 1ª vira principal), set_card (edita alma/título/nome do próprio), activate (publica, sai de draft, exige ≥1 imagem), set_visibility (isPublic true=Explorar+slug / false=privado). GESTÃO de imagem (por url, pegue as urls atuais em action=get campo imageUrls): remove_image (tira uma), set_main_image (define a principal), reorder_images (nova ordem via orderedUrls, posição 0=principal), e delete (apaga o personagem, permanente). FICHA (generate_sheet, COBRA 450 Sinapses): desenha a página-pôster do personagem
|
|
146
|
+
description: "Personagens (character sheets) do Sapiens — a tabela `influencers`: personagem reutilizável com imagens (pra character-lock em geração) + alma (systemPrompt), tudo amarrado à conta do dono do token (sem admin). Sub-actions: list_public (catálogo global de personagens públicos do Explorar; cada um traz mainImageUrl/imageUrls usáveis direto como referenceImageUrls em sapiens_image; sem custo, sem login), get (detalhe de 1 por characterId — público+ativo qualquer um vê, draft/privado só o dono; systemPrompt só volta pro dono), list_mine (os personagens do próprio user, inclui drafts/privados), create (cria rascunho na conta: name + gender + opcional title/systemPrompt), add_image (adiciona imagem ao próprio personagem via imageUrl público OU sourceImageId da galeria; 1ª vira principal), set_card (edita alma/título/nome do próprio), activate (publica, sai de draft, exige ≥1 imagem), set_visibility (isPublic true=Explorar+slug / false=privado). GESTÃO de imagem (por url, pegue as urls atuais em action=get campo imageUrls): remove_image (tira uma), set_main_image (define a principal), reorder_images (nova ordem via orderedUrls, posição 0=principal), e delete (apaga o personagem, permanente). FICHA (generate_sheet, COBRA 450 Sinapses): desenha a página-pôster do personagem no traço das imagens que ele já tem (exige pelo menos uma), em duas orientações (arg `orientation`): 'portrait' (default) é a página de processo, pose, expressões, trocas de roupa e adereços soltos na folha; 'landscape' é a prancha larga, com a volta completa à esquerda, a figura grande no meio, poses à direita, estudos de silhueta, expressão e detalhe embaixo e um painel CHARACTER ID na ponta. A personalidade sai da alma (systemPrompt) e é ela que escolhe roupa e objeto, então personagem com alma escrita rende ficha melhor. Cada geração é um estilo NOVO e elas acumulam no personagem (campo sheetUrls em action=get), nenhuma apaga a anterior, e a ficha já entra na galeria dele como referência das próximas gerações. É geração síncrona: se voltar Timeout, cheque action=get antes de repetir, senão cobra duas vezes. Fluxo de criação: create → add_image (1+) → set_card (opcional) → activate → set_visibility isPublic=true. Pra usar um personagem público como referência numa geração, pegue mainImageUrl em list_public/get e passe em sapiens_image referenceImageUrls.",
|
|
147
147
|
schema: characterSchema,
|
|
148
148
|
handler: character,
|
|
149
149
|
},
|
|
150
150
|
sapiens_profile: {
|
|
151
|
-
description: "O 'tudo junto' do perfil do user (/u/<username>), user-tier. Agrega o que mora no perfil mas estava fora do MCP: identidade + nível/XP + saldo, badges (conquistas) e golden tools (favoritos do aitag). Sub-actions de LEITURA: get (card completo: identidade + nível + saldo + badges + golden tools), badges (só as conquistas, lista cheia), golden_tools (só os favoritos do aitag, lista cheia), notifications (suas notificações recentes do sino + contagem de não-lidas), mark_read (marca uma notificationId ou TODAS as não-lidas como lidas). Sub-actions de ESCRITA (mexem na SUA conta; identidade sempre da sessão): follow/unfollow (seguir/deixar de seguir outro user por followingId=users:_id, descoberto via sapiens_community participants/search_users), update_bio (edita a sua bio), update_username (troca o seu @; inválido/tomado volta {success:false,error}). FAVORITOS de ferramentas de IA (Golden Tools do aitag; o toolId vem de sapiens_repertorio action=search_tools): favorite_tool (favorita/desfavorita, estrela), favorite_lists (suas listas), create_favorite_list (listName+emoji/description/isPublic), add_to_favorite_list/remove_from_favorite_list (toolId+listId), delete_favorite_list (listId). As partes grandes do perfil NÃO são duplicadas aqui, têm tool própria: imagens geradas/publicadas=sapiens_gallery, repertório (filmes/séries/jogos/livros/música)=sapiens_repertorio, personagens=sapiens_character, persona/arquétipo MBTI=sapiens_persona action=my_profile, saldo detalhado por bucket=sapiens_meta action=subscription. Monta a partir de queries já em prod (sem custo).",
|
|
151
|
+
description: "O 'tudo junto' do perfil do user (/u/<username>), user-tier. Agrega o que mora no perfil mas estava fora do MCP: identidade + nível/XP + saldo, badges (conquistas) e golden tools (favoritos do aitag). Sub-actions de LEITURA: get (card completo: identidade + nível + saldo + badges + golden tools), soul (a sapiens-soul: retrato do momento no contrato sapiens.soul/v1, identidade + persona + repertório público + tese, derivado e datado; quando o user pedir 'minha soul' ou 'meu retrato do Sapiens' pro projeto dele, chame e salve como sapiens-soul.json — snapshot, não conexão viva), badges (só as conquistas, lista cheia), golden_tools (só os favoritos do aitag, lista cheia), notifications (suas notificações recentes do sino + contagem de não-lidas), mark_read (marca uma notificationId ou TODAS as não-lidas como lidas). Sub-actions de ESCRITA (mexem na SUA conta; identidade sempre da sessão): follow/unfollow (seguir/deixar de seguir outro user por followingId=users:_id, descoberto via sapiens_community participants/search_users), update_bio (edita a sua bio), update_username (troca o seu @; inválido/tomado volta {success:false,error}). FAVORITOS de ferramentas de IA (Golden Tools do aitag; o toolId vem de sapiens_repertorio action=search_tools): favorite_tool (favorita/desfavorita, estrela), favorite_lists (suas listas), create_favorite_list (listName+emoji/description/isPublic), add_to_favorite_list/remove_from_favorite_list (toolId+listId), delete_favorite_list (listId). As partes grandes do perfil NÃO são duplicadas aqui, têm tool própria: imagens geradas/publicadas=sapiens_gallery, repertório (filmes/séries/jogos/livros/música)=sapiens_repertorio, personagens=sapiens_character, persona/arquétipo MBTI=sapiens_persona action=my_profile, saldo detalhado por bucket=sapiens_meta action=subscription. Monta a partir de queries já em prod (sem custo).",
|
|
152
152
|
schema: profileSchema,
|
|
153
153
|
handler: profile,
|
|
154
154
|
},
|
|
@@ -265,7 +265,7 @@ const TOOL_TITLES = {
|
|
|
265
265
|
sapiens_write: "Artigos do Perfil",
|
|
266
266
|
sapiens_quote_pop: "Coluna Sapiens/Repertório",
|
|
267
267
|
sapiens_search: "Buscar Artigos",
|
|
268
|
-
sapiens_studios: "
|
|
268
|
+
sapiens_studios: "Meu Studio & Estúdios",
|
|
269
269
|
sapiens_persona: "Persona (MBTI)",
|
|
270
270
|
sapiens_helen: "Voz Helen (TTS)",
|
|
271
271
|
sapiens_musicator: "Musicator",
|
package/dist/skills.js
CHANGED
|
@@ -262,48 +262,40 @@ Aí não é geração base, é o Studio dela. Veja a skill \`studio\`.`,
|
|
|
262
262
|
},
|
|
263
263
|
{
|
|
264
264
|
name: "studio",
|
|
265
|
-
title: "Meu Studio
|
|
266
|
-
description: "O studio é
|
|
265
|
+
title: "Meu Studio",
|
|
266
|
+
description: "O studio é a PÁGINA de portfólio da empresa da pessoa (obra, time, endereço público), e você funda o dela pelo chat. Puxe quando ela falar do studio dela, quiser fundar um, mostrar a casa ou montar time.",
|
|
267
267
|
body: `## O que o studio é
|
|
268
268
|
|
|
269
|
-
O studio é
|
|
269
|
+
O studio é a **página de portfólio** da empresa da pessoa: um endereço público (\`sapiensinteticos.com/studios/<slug>\`) com a obra, o time e o que a casa faz. Não é uma paleta de ferramentas, não tem níveis, e **não é identidade de geração**: isso morreu.
|
|
270
270
|
|
|
271
|
-
|
|
271
|
+
Uma pessoa pode ter até 4 studios e integrar até 4. \`sapiens_studios action=mine\` mostra o primário dela: nome, endereço público, marca e tamanho do time. O servidor resolve pela SESSÃO, você nunca passa id.
|
|
272
272
|
|
|
273
|
-
|
|
274
|
-
- **A identidade de geração.** Marca e personagem-operador, que o \`useStudio\` aplica.
|
|
273
|
+
## Fundar
|
|
275
274
|
|
|
276
|
-
|
|
275
|
+
\`sapiens_studios action=create name="<nome da casa>"\` funda. De graça, sem Sinapse.
|
|
277
276
|
|
|
278
|
-
|
|
277
|
+
- **Pergunte o nome, nunca invente.** O endereço público sai dele, em kebab-case, e é o que vai no cartão de visita da pessoa.
|
|
278
|
+
- \`description\` (uma linha) é opcional e aparece embaixo do nome. \`brandSlug\` ancora a marca dela, se ela já tiver uma.
|
|
279
|
+
- Nasce **privado**, com ela como fundadora. Publicar é decisão dela, na página.
|
|
280
|
+
- Bateu o teto de 4: o erro diz. Não insista, ela sai de um pra fundar outro.
|
|
279
281
|
|
|
280
|
-
|
|
282
|
+
Depois de fundar, entregue o link e pare. Vestir a página (capa, logo, sobre, seções, ordem da obra) é no modo edição da própria página, não por aqui.
|
|
281
283
|
|
|
282
|
-
|
|
284
|
+
## O studio NÃO entra na geração
|
|
283
285
|
|
|
284
|
-
|
|
286
|
+
Gerar imagem "no studio dela" não existe. Se ela pedir "na minha marca" ou "do meu jeito", o caminho é explícito e é seu:
|
|
285
287
|
|
|
286
|
-
|
|
288
|
+
- **marca da casa** → \`sapiens_image\` com \`brandSlug\` (veja \`sapiens_brand\`);
|
|
289
|
+
- **personagem dela** → \`influencerId\` (veja \`sapiens_character\`);
|
|
290
|
+
- **o traço da casa** → \`templateSlug\`.
|
|
287
291
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
\`sapiens_studios action=mine\` mostra nome, endereço público, marca, operador e o tamanho do time.
|
|
291
|
-
|
|
292
|
-
Se você pediu \`useStudio=true\` e voltou \`studioApplied=false\`, a pessoa ainda não fundou uma casa: avise e aponte /dashboard/studio.
|
|
292
|
+
Pergunte qual, não adivinhe.
|
|
293
293
|
|
|
294
294
|
## O time
|
|
295
295
|
|
|
296
296
|
Gente entra por convite, e o convite exige **follow mútuo**: os dois precisam já se seguir. Personagem do próprio elenco entra sem convite, é posse. Teto de 4 pessoas por casa.
|
|
297
297
|
|
|
298
|
-
A obra da página é automática por default: a soma dos Destaques de quem está no time. Se alguém empurrar uma peça à mão, ela passa a ser curada. Tudo isso se faz na página, não por aqui
|
|
299
|
-
|
|
300
|
-
## Emancipação
|
|
301
|
-
|
|
302
|
-
O passo grande: quando o membro quer a casa PRÓPRIA dele, site ou produto próprio, FORA do Sapiens.
|
|
303
|
-
|
|
304
|
-
\`sapiens_studios action=emancipar\` devolve o blueprint pra VOCÊ construir na infra DELE (Vercel, Convex e domínio dele), começando pela Fundação e seguindo um módulo por vez (\`action=module module=<slug>\`: fundacao, sapiens-connect, telegram, email, auth).
|
|
305
|
-
|
|
306
|
-
Confirme cada passo. Nunca hospede no Sapiens. Siga o gosto dele. É complexo: conduza com calma.`,
|
|
298
|
+
A obra da página é automática por default: a soma dos Destaques de quem está no time. Se alguém empurrar uma peça à mão, ela passa a ser curada. Tudo isso se faz na página, não por aqui.`,
|
|
307
299
|
},
|
|
308
300
|
{
|
|
309
301
|
name: "tirinha",
|
|
@@ -411,6 +403,65 @@ Sem bloco companion, opere na voz neutra da casa.`,
|
|
|
411
403
|
|
|
412
404
|
**O crédito em Sinapses sai na APROVAÇÃO dele, não na hora.** Não prometa Sinapse no momento do claim. Diga que a prova foi enviada e que o crédito vem quando for aprovada.`,
|
|
413
405
|
},
|
|
406
|
+
{
|
|
407
|
+
name: "minha-soul",
|
|
408
|
+
title: "Instalar a soul do usuário neste projeto",
|
|
409
|
+
description: "Transforma o retrato do usuário no Sapiens numa skill local do projeto atual, pra toda conversa nesta pasta já saber quem é o dono. Puxe quando ele disser 'instala minha soul', 'meu Claude precisa me conhecer', 'personaliza esse projeto comigo'.",
|
|
410
|
+
body: `## O que você vai fazer
|
|
411
|
+
|
|
412
|
+
Escrever a soul da pessoa como skill LOCAL do projeto onde vocês estão. Depois disso, toda conversa nesta pasta abre já sabendo quem é o dono: o gosto, o jeito de pensar, o repertório. Sem MCP no meio, sem chave, sem rede.
|
|
413
|
+
|
|
414
|
+
## Passo a passo
|
|
415
|
+
|
|
416
|
+
1. \`sapiens_profile action=soul\` devolve o contrato \`sapiens.soul/v1\`. Não cobra Sinapse.
|
|
417
|
+
2. Escreva \`.claude/skills/sapiens-soul/SKILL.md\` na raiz do projeto atual, no molde abaixo. Pasta que não existe, você cria. Arquivo que já existe, você sobrescreve: é o retrato de hoje.
|
|
418
|
+
3. Confirme em UMA linha: o caminho do arquivo e a data do retrato. Não despeje o JSON na conversa.
|
|
419
|
+
|
|
420
|
+
Se a pessoa não estiver dentro de um projeto (conversa sem pasta, claude.ai), diga onde o arquivo deveria morar e ofereça o conteúdo pra ela colar.
|
|
421
|
+
|
|
422
|
+
## O molde
|
|
423
|
+
|
|
424
|
+
O corpo em prosa é o que o modelo lê rápido; o JSON no fim é pra quem quiser o dado estruturado. Preencha com o que veio da soul e corte a seção que voltou vazia.
|
|
425
|
+
|
|
426
|
+
\`\`\`\`markdown
|
|
427
|
+
---
|
|
428
|
+
name: sapiens-soul
|
|
429
|
+
description: Quem é o dono deste projeto (nome, @, persona cognitiva, repertório e tese, vindos do Sapiens Sintéticos). Puxe antes de escrever copy, escolher exemplo, nomear coisa, decidir estética ou sugerir referência.
|
|
430
|
+
---
|
|
431
|
+
|
|
432
|
+
# A soul de <nome ou @handle>
|
|
433
|
+
|
|
434
|
+
Retrato de <data legível do generatedAt>, contrato sapiens.soul/v1. É um instantâneo, não uma conexão viva.
|
|
435
|
+
|
|
436
|
+
## Quem é
|
|
437
|
+
<subject: nome, @, bio, nível, badges, link do perfil>
|
|
438
|
+
|
|
439
|
+
## Como pensa
|
|
440
|
+
<cognition: código, persona, e os quatro eixos com polo e confiança, em uma linha cada>
|
|
441
|
+
|
|
442
|
+
## Repertório
|
|
443
|
+
<repertorio: total público, gêneros e tags que mais aparecem, nota média, pessoas que ele acompanha, e as obras recentes que dizem alguma coisa sobre o gosto>
|
|
444
|
+
|
|
445
|
+
## Tese
|
|
446
|
+
<tese, quando veio>
|
|
447
|
+
|
|
448
|
+
## Como usar isto
|
|
449
|
+
Escrevendo pra essa pessoa ou no lugar dela: puxe a referência do repertório dela antes de inventar uma. O jeito de decidir está nos eixos. Na dúvida entre duas opções, escolha a que combina com o que já está aqui.
|
|
450
|
+
|
|
451
|
+
## Dados brutos
|
|
452
|
+
\`\`\`json
|
|
453
|
+
<o contrato inteiro, como veio>
|
|
454
|
+
\`\`\`
|
|
455
|
+
\`\`\`\`
|
|
456
|
+
|
|
457
|
+
## Atualizar
|
|
458
|
+
|
|
459
|
+
O retrato envelhece. Quando a pessoa pedir, rode a action de novo e sobrescreva o arquivo. Nada mais precisa mudar.
|
|
460
|
+
|
|
461
|
+
## O que nunca entra
|
|
462
|
+
|
|
463
|
+
A soul é derivada e já sai filtrada da casa: saldo, transações, e-mail, contatos, conversas e criações privadas não viajam. Não tente completar o retrato com dado de outra tool.`,
|
|
464
|
+
},
|
|
414
465
|
];
|
|
415
466
|
export const SKILLS = Object.fromEntries(SKILL_LIST.map((s) => [s.name, s]));
|
|
416
467
|
/** Monta o SKILL.md completo (frontmatter do formato aberto + corpo). */
|
package/dist/tools/character.js
CHANGED
|
@@ -24,6 +24,9 @@ import { convexQuery, convexMutation, convexAction, getSessionToken } from "../c
|
|
|
24
24
|
* - remove_image: tira UMA imagem do próprio personagem (por url).
|
|
25
25
|
* - set_main_image: define a principal (por url, entre as que já existem).
|
|
26
26
|
* - reorder_images: reordena as imagens (posição 0 = principal).
|
|
27
|
+
* - generate_sheet: desenha a ficha do personagem (COBRA), vertical ou
|
|
28
|
+
* horizontal (`orientation`). A ficha entra na galeria dele e
|
|
29
|
+
* já serve de referência; elas acumulam.
|
|
27
30
|
* - delete: apaga o próprio personagem (permanente).
|
|
28
31
|
*
|
|
29
32
|
* Fluxo típico de criação: create → add_image (1+) → set_card (opcional) →
|
|
@@ -72,7 +75,7 @@ export const characterSchema = z.object({
|
|
|
72
75
|
.describe("Pra create/set_card: a 'alma' do personagem (personalidade, jeito de falar, contexto). Usado no chat e como guia de geração."),
|
|
73
76
|
imageUrl: httpUrl()
|
|
74
77
|
.optional()
|
|
75
|
-
.describe("Pra add_image: URL pública da imagem (Bunny CDN / Convex storage). Use a `url` que sapiens_image/sapiens_gallery devolvem. Pra remove_image/set_main_image: a url da imagem JÁ no personagem (pegue via action=get, campo imageUrls)."),
|
|
78
|
+
.describe("Pra add_image: URL pública da imagem (Bunny CDN / Convex storage). Use a `url` que sapiens_image/sapiens_gallery devolvem. Pra remove_image/set_main_image: a url da imagem JÁ no personagem (pegue via action=get, campo imageUrls, ou sheetUrls pra apagar uma ficha)."),
|
|
76
79
|
orderedUrls: z
|
|
77
80
|
.array(z.string())
|
|
78
81
|
.optional()
|
|
@@ -89,6 +92,10 @@ export const characterSchema = z.object({
|
|
|
89
92
|
.boolean()
|
|
90
93
|
.optional()
|
|
91
94
|
.describe("Pra set_visibility: true = público no Explorar (gera slug), false = privado."),
|
|
95
|
+
orientation: z
|
|
96
|
+
.enum(["portrait", "landscape"])
|
|
97
|
+
.optional()
|
|
98
|
+
.describe("Pra generate_sheet: 'portrait' (default) é a página de processo vertical, composição livre, sem texto. 'landscape' é a prancha larga: volta completa à esquerda, figura grande no meio, poses à direita, estudos de silhueta/expressão/detalhe embaixo e painel CHARACTER ID na ponta. As duas acumulam no personagem, uma não substitui a outra."),
|
|
92
99
|
});
|
|
93
100
|
export async function character(args) {
|
|
94
101
|
// -------- list_public: catálogo global (sessionToken opcional, marca `mine`) --------
|
|
@@ -243,7 +250,9 @@ export async function character(args) {
|
|
|
243
250
|
}
|
|
244
251
|
// -------- generate_sheet: a ficha (página-pôster) do personagem --------
|
|
245
252
|
// Geração SÍNCRONA que COBRA: cai na regra do timeout. Se voltar Timeout,
|
|
246
|
-
// NÃO repita às cegas: confira em action=get (campo
|
|
253
|
+
// NÃO repita às cegas: confira em action=get (campo imageUrls) se a peça caiu.
|
|
254
|
+
// A ficha entra na galeria do personagem, então já vira referência das
|
|
255
|
+
// próximas gerações sem passo extra.
|
|
247
256
|
if (args.action === "generate_sheet") {
|
|
248
257
|
if (!args.characterId)
|
|
249
258
|
throw new Error("action=generate_sheet exige characterId.");
|
|
@@ -251,6 +260,7 @@ export async function character(args) {
|
|
|
251
260
|
return await convexAction("characterSheetActions:mcpGenerateCharacterSheet", {
|
|
252
261
|
sessionToken,
|
|
253
262
|
influencerId: args.characterId,
|
|
263
|
+
orientation: args.orientation,
|
|
254
264
|
});
|
|
255
265
|
}
|
|
256
266
|
// -------- delete: apaga o próprio personagem (permanente) --------
|
package/dist/tools/gallery.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { readFile } from "node:fs/promises";
|
|
3
|
-
import { convexAction, getSessionToken, isRemoteContext } from "../convexClient.js";
|
|
3
|
+
import { convexAction, convexMutation, getSessionToken, isRemoteContext, } from "../convexClient.js";
|
|
4
4
|
/**
|
|
5
5
|
* Galeria do usuário: browse, publicação e UPLOAD de peça de fora.
|
|
6
6
|
* Wrapper sobre `desktopMcp.galleryList` / `galleryGet` / `gallerySetPublic` e
|
|
@@ -27,7 +27,15 @@ import { convexAction, getSessionToken, isRemoteContext } from "../convexClient.
|
|
|
27
27
|
* e um motor terceiro só renderizou é ingest.
|
|
28
28
|
*/
|
|
29
29
|
export const gallerySchema = z.object({
|
|
30
|
-
action: z.enum([
|
|
30
|
+
action: z.enum([
|
|
31
|
+
"list",
|
|
32
|
+
"get",
|
|
33
|
+
"publish",
|
|
34
|
+
"unpublish",
|
|
35
|
+
"upload",
|
|
36
|
+
"ingest",
|
|
37
|
+
"refs",
|
|
38
|
+
]),
|
|
31
39
|
limit: z
|
|
32
40
|
.number()
|
|
33
41
|
.int()
|
|
@@ -42,7 +50,7 @@ export const gallerySchema = z.object({
|
|
|
42
50
|
imageId: z
|
|
43
51
|
.string()
|
|
44
52
|
.optional()
|
|
45
|
-
.describe("generatedImages:_id (obrigatório pra action=get/publish/unpublish)"),
|
|
53
|
+
.describe("generatedImages:_id (obrigatório pra action=get/publish/unpublish/refs)"),
|
|
46
54
|
includeBase64: z
|
|
47
55
|
.boolean()
|
|
48
56
|
.optional()
|
|
@@ -89,11 +97,18 @@ export const gallerySchema = z.object({
|
|
|
89
97
|
.string()
|
|
90
98
|
.optional()
|
|
91
99
|
.describe("action=ingest: resolução ('720p', '1080p'). Default 720p."),
|
|
100
|
+
// Aceita lista OU string com os ids separados por vírgula. O segundo formato
|
|
101
|
+
// existe porque alguns clientes MCP serializam array como texto ao repassar a
|
|
102
|
+
// chamada, e aí o servidor recusava com "Expected array, received string" sem
|
|
103
|
+
// que houvesse nada de errado com o pedido. Normalizado logo abaixo.
|
|
92
104
|
referenceImageIds: z
|
|
93
|
-
.array(z.string())
|
|
94
|
-
.max(8)
|
|
105
|
+
.union([z.array(z.string()), z.string()])
|
|
95
106
|
.optional()
|
|
96
|
-
.describe("action=ingest: generatedImages:_id das peças DA CASA que serviram de referência (folha de storyboard, ficha de personagem, frame inicial). Ficam acopladas à peça
|
|
107
|
+
.describe("action=ingest/refs: generatedImages:_id das peças DA CASA que serviram de referência (folha de storyboard, ficha de personagem, frame inicial). Ficam acopladas à peça e aparecem na ficha dela: é o que prova que a receita saiu daqui. Só peça sua entra, no máximo 8. Aceita lista ou os ids separados por vírgula."),
|
|
108
|
+
replace: z
|
|
109
|
+
.boolean()
|
|
110
|
+
.optional()
|
|
111
|
+
.describe("action=refs: false (default) SOMA às referências que já existem; true troca a lista inteira. Pra limpar tudo, mande a lista vazia com replace=true."),
|
|
97
112
|
uploadedSource: z
|
|
98
113
|
.string()
|
|
99
114
|
.optional()
|
|
@@ -190,6 +205,23 @@ async function resolveUploadBytes(args) {
|
|
|
190
205
|
}
|
|
191
206
|
throw new Error("action=upload exige a peça: sourceUrl (https), filePath (local, stdio) ou base64.");
|
|
192
207
|
}
|
|
208
|
+
/**
|
|
209
|
+
* Normaliza `referenceImageIds` pro formato que o Convex espera (lista).
|
|
210
|
+
*
|
|
211
|
+
* O schema aceita lista ou string com vírgulas porque cliente MCP que serializa
|
|
212
|
+
* array como texto existe de verdade, e o erro que ele produzia ("Expected
|
|
213
|
+
* array, received string") não dizia nada sobre como consertar. Aqui a diferença
|
|
214
|
+
* morre, e o backend continua recebendo sempre uma lista.
|
|
215
|
+
*/
|
|
216
|
+
function normalizeRefIds(raw) {
|
|
217
|
+
if (!raw)
|
|
218
|
+
return [];
|
|
219
|
+
const lista = Array.isArray(raw) ? raw : raw.split(",");
|
|
220
|
+
return lista
|
|
221
|
+
.map((id) => id.trim().replace(/^["'[]+|["'\]]+$/g, ""))
|
|
222
|
+
.filter(Boolean)
|
|
223
|
+
.slice(0, 8);
|
|
224
|
+
}
|
|
193
225
|
export async function gallery(args) {
|
|
194
226
|
const sessionToken = getSessionToken();
|
|
195
227
|
if (args.action === "list") {
|
|
@@ -257,11 +289,30 @@ export async function gallery(args) {
|
|
|
257
289
|
externalCost: args.externalCost,
|
|
258
290
|
aspectRatio: args.aspectRatio,
|
|
259
291
|
size: args.size,
|
|
260
|
-
referenceImageIds: args.referenceImageIds,
|
|
292
|
+
referenceImageIds: normalizeRefIds(args.referenceImageIds),
|
|
261
293
|
});
|
|
262
294
|
return {
|
|
263
295
|
...result,
|
|
264
296
|
aviso: "Peça NATIVA: entra na timeline, publica e vai pra comunidade como qualquer geração da casa. Custo em Sinapses é 0 e ela NÃO leva assinatura C2PA, porque o motor rodou fora. Use ingest só quando a receita (folha, personagem, prompt) foi da casa; peça achada pronta é action=upload.",
|
|
265
297
|
};
|
|
266
298
|
}
|
|
299
|
+
// refs: acopla peças da casa a uma peça que JÁ existe (upload ou ingest).
|
|
300
|
+
// A ingestão aceita refs no nascimento, mas quem sobe raramente tem os ids em
|
|
301
|
+
// mãos na hora; e o upload não tinha lugar nenhum pra dizer de onde veio a
|
|
302
|
+
// direção. Escreve proveniência e nada mais: upload continua sem publicar.
|
|
303
|
+
if (args.action === "refs") {
|
|
304
|
+
if (!args.imageId) {
|
|
305
|
+
throw new Error("action=refs exige imageId: a peça que RECEBE as referências. Use action=list pra achar.");
|
|
306
|
+
}
|
|
307
|
+
const referenceImageIds = normalizeRefIds(args.referenceImageIds);
|
|
308
|
+
if (!referenceImageIds.length && !args.replace) {
|
|
309
|
+
throw new Error("action=refs exige referenceImageIds: os ids das peças da casa que serviram de referência. Pra LIMPAR as referências, mande replace=true com a lista vazia.");
|
|
310
|
+
}
|
|
311
|
+
return await convexMutation("externalIngest:mcpAttachReferences", {
|
|
312
|
+
sessionToken,
|
|
313
|
+
imageId: args.imageId,
|
|
314
|
+
referenceImageIds,
|
|
315
|
+
replace: args.replace,
|
|
316
|
+
});
|
|
317
|
+
}
|
|
267
318
|
}
|
package/dist/tools/image.js
CHANGED
|
@@ -77,14 +77,10 @@ export const imageSchema = z.object({
|
|
|
77
77
|
.string()
|
|
78
78
|
.optional()
|
|
79
79
|
.describe("Slug de um template de imagem (super-prompt travado da casa). Quando setado, o `prompt` vira só a CENA (quem + pose + objeto-conceito) e o template embrulha com o estilo + fundo + enquadramento + ref de traço da casa. Ex: 'retrato-sapiens-v1' = retrato editorial cartoon de UM personagem no grid verde Sapiens (mesma 'mão' dos artigos). O template define model/aspect/size default (sobreponíveis) e injeta a ref da Helen como âncora de traço quando você não passa referenceImageUrls própria (passar refs = trocar quem aparece, mantendo o estilo). Mutuamente exclusivo com brandSlug. Vale em action=generate, mode=create."),
|
|
80
|
-
useStudio: z
|
|
81
|
-
.boolean()
|
|
82
|
-
.optional()
|
|
83
|
-
.describe("Quando true, gera SEGUINDO o studio do user (o 'Meu Studio', ÚNICO, resolvido pela sessão — você NÃO passa id): marca + personagem-operador + a vibe + os presets do bloco de imagem entram sozinhos (o explícito sempre vence). O retorno traz studioApplied: true se aplicou o studio, false se caiu no Sapiens base (sem studio montado — aí avise o user). É o 'criar no meu studio' do Nível 2, e gerar assim faz o studio evoluir. SEM useStudio = geração base, fora da identidade dele: não misture. Cheque o studio com sapiens_studios action=mine. Vale em action=generate."),
|
|
84
80
|
influencerId: z
|
|
85
81
|
.string()
|
|
86
82
|
.optional()
|
|
87
|
-
.describe("ID de personagem (influencer) pra character-lock
|
|
83
|
+
.describe("ID de personagem (influencer) pra character-lock: a imagem sai com ESSE personagem. Descubra o id com sapiens_character."),
|
|
88
84
|
loraIntensity: z
|
|
89
85
|
.enum(["suave", "medio", "forte"])
|
|
90
86
|
.optional()
|
|
@@ -216,25 +212,14 @@ export async function image(args) {
|
|
|
216
212
|
brandSlug: args.brandSlug,
|
|
217
213
|
brandMark: args.brandMark,
|
|
218
214
|
templateSlug: args.templateSlug,
|
|
219
|
-
useStudio: args.useStudio,
|
|
220
215
|
influencerId: args.influencerId,
|
|
221
216
|
loraIntensity: args.loraIntensity,
|
|
222
217
|
});
|
|
223
|
-
const studioApplied = result?.studioApplied === true;
|
|
224
218
|
return {
|
|
225
219
|
imageId: result?.imageId,
|
|
226
220
|
url: result?.url,
|
|
227
221
|
webUrl: result?.imageId ? `https://sapiensinteticos.com/imagem/${result.imageId}` : undefined,
|
|
228
222
|
mimeType: result?.mimeType,
|
|
229
|
-
// studioApplied=true só quando useStudio achou e aplicou o studio do user.
|
|
230
|
-
// false = geração base. É o sinal pra não confundir studio com base.
|
|
231
|
-
studioApplied,
|
|
232
|
-
// Pediu o studio mas não há um montado: caiu no base, avise o user.
|
|
233
|
-
...(args.useStudio && !studioApplied
|
|
234
|
-
? {
|
|
235
|
-
note: "Você pediu o seu studio, mas não há um montado: gerei no Sapiens base. Monte o seu studio em sapiensinteticos.com/dashboard/studio (ferramentas + marca + a vibe).",
|
|
236
|
-
}
|
|
237
|
-
: {}),
|
|
238
223
|
// Não incluir base64 no retorno (polui contexto). Quem quiser bytes
|
|
239
224
|
// chama sapiens_gallery action=get com includeBase64=true.
|
|
240
225
|
};
|
package/dist/tools/profile.js
CHANGED
|
@@ -18,6 +18,10 @@ import { convexQuery, convexMutation, getSessionToken } from "../convexClient.js
|
|
|
18
18
|
*
|
|
19
19
|
* Sub-actions:
|
|
20
20
|
* - get: card completo (identidade + nível + saldo + badges + golden tools).
|
|
21
|
+
* - soul: a sapiens-soul: retrato do momento (contrato sapiens.soul/v1,
|
|
22
|
+
* identidade + persona + repertório + tese, derivado e datado).
|
|
23
|
+
* Salve como sapiens-soul.json no projeto do usuário quando ele
|
|
24
|
+
* pedir "pega minha soul / meu retrato do Sapiens".
|
|
21
25
|
* - badges: só as conquistas (lista cheia).
|
|
22
26
|
* - golden_tools: só os favoritos do aitag (lista cheia).
|
|
23
27
|
* - notifications: suas notificações recentes (sino) + contagem de não-lidas.
|
|
@@ -33,6 +37,7 @@ import { convexQuery, convexMutation, getSessionToken } from "../convexClient.js
|
|
|
33
37
|
export const profileSchema = z.object({
|
|
34
38
|
action: z.enum([
|
|
35
39
|
"get",
|
|
40
|
+
"soul",
|
|
36
41
|
"badges",
|
|
37
42
|
"golden_tools",
|
|
38
43
|
"notifications",
|
|
@@ -119,6 +124,15 @@ function mapTools(rows) {
|
|
|
119
124
|
}
|
|
120
125
|
export async function profile(args) {
|
|
121
126
|
const sessionToken = getSessionToken();
|
|
127
|
+
// A soul: retrato do momento (contrato sapiens.soul/v1). Autentica pelo
|
|
128
|
+
// próprio sessionToken; token de membro tem acesso total, então vem inteira.
|
|
129
|
+
if (args.action === "soul") {
|
|
130
|
+
const soul = await convexQuery("soulContract:getForToken", { sessionToken });
|
|
131
|
+
return {
|
|
132
|
+
...soul,
|
|
133
|
+
note: "Snapshot datado (generatedAt), não é conexão viva. Salve como sapiens-soul.json no projeto do usuário; pra atualizar, rode a action de novo e sobrescreva o arquivo.",
|
|
134
|
+
};
|
|
135
|
+
}
|
|
122
136
|
// notifications/mark_read autenticam pelo próprio sessionToken (requireMcpUser
|
|
123
137
|
// no Convex), não precisam do resolveUser — atalham antes.
|
|
124
138
|
if (args.action === "notifications") {
|
package/dist/tools/studios.js
CHANGED
|
@@ -1,31 +1,42 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { convexAction,
|
|
2
|
+
import { convexAction, convexMutation, getSessionToken } from "../convexClient.js";
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Duas coisas com o mesmo nome, e o `action` separa as duas:
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
* 1. O CATÁLOGO dos estúdios/experimentos da casa (`list`/`get`): info estática
|
|
7
|
+
* com URL do dashboard, status e tags, pro Claude rotear o user pro lugar
|
|
8
|
+
* certo quando ele pede coisa que o plugin não cobre.
|
|
9
|
+
* 2. O STUDIO DO MEMBRO (`mine`/`create`): a página de portfólio da empresa
|
|
10
|
+
* dele. Fundar é aqui; vestir a página (capa, logo, sobre, seções) e montar
|
|
11
|
+
* o time é na própria página, no modo edição.
|
|
10
12
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
13
|
+
* A Emancipação (o antigo "Nível 3", blueprint pra construir a casa própria na
|
|
14
|
+
* infra do membro) saiu em ago/2026 junto com os níveis: o studio virou perfil
|
|
15
|
+
* de empresa, não uma jornada. As queries `studioBlueprints:mcp*` seguem no
|
|
16
|
+
* backend só como aviso pra pacote publicado que ainda chama.
|
|
14
17
|
*/
|
|
15
18
|
export const studiosSchema = z.object({
|
|
16
19
|
action: z
|
|
17
|
-
.enum(["list", "get", "publishable_url", "mine", "
|
|
18
|
-
.describe("mine = o SEU studio (
|
|
19
|
-
"
|
|
20
|
-
"
|
|
20
|
+
.enum(["list", "get", "publishable_url", "mine", "create"])
|
|
21
|
+
.describe("mine = o SEU studio (a página de portfólio da sua casa): nome, endereço público, marca, operador e tamanho do time. " +
|
|
22
|
+
"create = FUNDA um studio novo na conta do user (exige 'name'). Nasce privado, com ele como fundador; publicar e vestir a página é na própria página. Teto de 4 por pessoa. " +
|
|
23
|
+
"list/get = catálogo de estúdios da casa. publishable_url = URL de artigo."),
|
|
21
24
|
studio: z
|
|
22
25
|
.string()
|
|
23
26
|
.optional()
|
|
24
27
|
.describe("Pra action=get: slug do estúdio (ex 'helen-voice', 'musicator', 'persona-sapiens', 'sapiens-shorts')."),
|
|
25
|
-
|
|
28
|
+
name: z
|
|
26
29
|
.string()
|
|
27
30
|
.optional()
|
|
28
|
-
.describe("Pra action=
|
|
31
|
+
.describe("Pra action=create: o nome da casa (obrigatório). O endereço público sai daí, em kebab-case. Pergunte ao user, não invente."),
|
|
32
|
+
description: z
|
|
33
|
+
.string()
|
|
34
|
+
.optional()
|
|
35
|
+
.describe("Pra action=create: uma linha do que a casa faz (até 200 chars). Opcional, mas é o que aparece embaixo do nome na página."),
|
|
36
|
+
brandSlug: z
|
|
37
|
+
.string()
|
|
38
|
+
.optional()
|
|
39
|
+
.describe("Pra action=create: marca da casa (slug de sapiens_brand). Opcional. Só passa marca que é do user."),
|
|
29
40
|
publishableId: z
|
|
30
41
|
.string()
|
|
31
42
|
.optional()
|
|
@@ -149,11 +160,11 @@ const STUDIOS = {
|
|
|
149
160
|
},
|
|
150
161
|
};
|
|
151
162
|
export async function studios(args) {
|
|
152
|
-
// action=mine: o studio PRIMÁRIO do user logado (
|
|
153
|
-
// dele), resumo non-PII
|
|
154
|
-
//
|
|
155
|
-
//
|
|
156
|
-
//
|
|
163
|
+
// action=mine: o studio PRIMÁRIO do user logado (a página de portfólio da casa
|
|
164
|
+
// dele), resumo non-PII. Os campos `level`/`levelLabel`/`tools`/`imageVibe`/
|
|
165
|
+
// `studioMcpRuns` vêm vazios: os níveis e as ferramentas à la carte morreram
|
|
166
|
+
// quando o studio virou página, e a geração ancorada (`useStudio`) morreu com
|
|
167
|
+
// ela; só continuam no retorno porque pacotes já publicados os imprimem.
|
|
157
168
|
if (args.action === "mine") {
|
|
158
169
|
const sessionToken = getSessionToken();
|
|
159
170
|
const studio = await convexAction("desktopMcp:studioMine", { sessionToken });
|
|
@@ -202,28 +213,24 @@ export async function studios(args) {
|
|
|
202
213
|
: "publishableId lookup ainda não suportado v1.3. Passe slug.",
|
|
203
214
|
};
|
|
204
215
|
}
|
|
205
|
-
// action=
|
|
206
|
-
//
|
|
207
|
-
if (args.action === "
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
return res; // { ok:false, error } — ex: sem studio montado ainda
|
|
212
|
-
return {
|
|
213
|
-
...res,
|
|
214
|
-
howto: "Blueprint-mestre da Emancipação (Nível 3). VOCÊ (o Claude do membro) constrói a casa dele NUMA PASTA NOVA, fora deste projeto, com Vercel + Convex + domínio DO MEMBRO. O Sapiens NÃO hospeda a casa. Conduza assim: (1) leia o `blueprint` (guia da Fundação) e execute passo a passo, confirmando com o membro ANTES de criar conta ou gastar (domínio); (2) o selo <meta name=\"sapiens-studio\"> é OBRIGATÓRIO pra verificação; (3) com a casa no ar, o membro submete a URL no Sapiens (Rito 'Studio no Ar', que paga Sinapses); (4) pra cada próximo módulo do `modules` que estiver 'ready', chame sapiens_studios action=module module=<slug>. Um módulo por vez, sem atropelar. É um passo grande: vá com calma e no gosto do membro.",
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
// action=module: o guia de UM módulo de infra, hidratado com a identidade do
|
|
218
|
-
// studio do membro. Chame depois da fundacao, um por vez.
|
|
219
|
-
if (args.action === "module") {
|
|
220
|
-
if (!args.module) {
|
|
221
|
-
throw new Error("action=module exige 'module' (slug do módulo de infra: fundacao, sapiens-connect, telegram, email, auth).");
|
|
216
|
+
// action=create: funda a casa. O servidor resolve o dono pelo sessionToken e
|
|
217
|
+
// devolve o endereço público já montado (quem chama não tem tela pra procurar).
|
|
218
|
+
if (args.action === "create") {
|
|
219
|
+
const name = (args.name ?? "").trim();
|
|
220
|
+
if (!name) {
|
|
221
|
+
throw new Error("action=create exige 'name' (o nome da casa). Pergunte ao user antes de inventar.");
|
|
222
222
|
}
|
|
223
223
|
const sessionToken = getSessionToken();
|
|
224
|
-
|
|
224
|
+
const res = await convexMutation("studios:mcpCreateStudio", {
|
|
225
225
|
sessionToken,
|
|
226
|
-
|
|
226
|
+
name,
|
|
227
|
+
description: args.description,
|
|
228
|
+
brandSlug: args.brandSlug,
|
|
227
229
|
});
|
|
230
|
+
return {
|
|
231
|
+
...res,
|
|
232
|
+
note: "Studio fundado, privado por enquanto. O user publica e veste a página (capa, logo, sobre, time, obra) em " +
|
|
233
|
+
`${APP}/studios/${res.slug} no modo edição. Convidar gente exige follow mútuo.`,
|
|
234
|
+
};
|
|
228
235
|
}
|
|
229
236
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sapiens-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.46.1",
|
|
4
4
|
"description": "MCP server pra operar o Sapiens Sintéticos (sapiensinteticos.com) pelo Claude Code: gerar imagem, escrever artigo, voz, música e mais, na sua conta. Login pelo código de sapiensinteticos.com/conectar-claude.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|