sapiens-mcp 1.46.3 → 1.46.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/dist/registry.js CHANGED
@@ -84,7 +84,7 @@ export const TOOLS = {
84
84
  handler: article,
85
85
  },
86
86
  sapiens_write: {
87
- description: "Artigos self-serve do PRÓPRIO usuário (qualquer conta logada, não só admin) espaço pessoal, aparece em /u/<username>, NÃO é o blog editorial. Sub-actions: generate (gera 1 artigo na voz Sapiens a partir de brief livre, ou reescrevendo um artigo publicado/texto teu; custa 400 Sinapses, reembolsa se falhar; salva como rascunho. Capa: por padrão gera uma capa-cortesia grátis; se você JÁ tem a imagem (gerou via sapiens_image, ou o artigo é sobre ela), passe coverImageId (id da tua galeria) ou coverImageUrl (host Sapiens) pra ELA virar a capa em vez da cortesia), list (teus artigos), get (1 artigo teu por id, corpo completo), update (edita title/content/excerpt/tldr), publish (publish=true publica no teu perfil, false volta pra rascunho). Identidade vem do sessionToken; cobra as Sinapses do dono do token. Pra blog editorial curado (owner-only) use sapiens_article. NOTA (generate): é SÍNCRONA (texto + capa) e cai na REGRA DO TIMEOUT; sem idempotência, repetir às cegas cria um 2º rascunho e cobra 400 de novo (cheque action=list antes; o artigo do timeout fica salvo como rascunho).",
87
+ description: "Artigos self-serve do PRÓPRIO usuário (qualquer conta logada, não só admin): espaço pessoal, aparece em /u/<username>, NÃO é o blog editorial. ESCOLHA A PORTA CERTA: texto que a PESSOA já escreveu vai em create (GRÁTIS, nada reescrito); IA só entra em generate (400 Sinapses). Gerar e depois sobrescrever com o texto original é queimar 400 à toa. Sub-actions: create (salva o texto pronto do autor: title obrigatório + content markdown; nasce rascunho, custo 0; brandSlug veste a peça com um design system (omitido, herda o padrão da conta) e é o que faz capa e imagens saírem no estilo DELE, não no da casa; coverImageId/coverImageUrl anexam uma capa que ele já tem, também de graça), generate (gera 1 artigo na voz Sapiens a partir de brief livre, ou reescrevendo um artigo publicado/texto teu; custa 400 Sinapses, reembolsa se falhar; salva como rascunho. Capa: por padrão gera uma capa-cortesia grátis, já no design system do autor quando ele tem um; se você JÁ tem a imagem (gerou via sapiens_image, ou o artigo é sobre ela), passe coverImageId (id da tua galeria) ou coverImageUrl (host Sapiens) pra ELA virar a capa em vez da cortesia), list (teus artigos), get (1 artigo teu por id, corpo completo), update (edita title/content/excerpt/tldr), publish (publish=true publica no teu perfil, false volta pra rascunho). Identidade vem do sessionToken; cobra as Sinapses do dono do token. Pra blog editorial curado (owner-only) use sapiens_article. NOTA (generate): é SÍNCRONA (texto + capa) e cai na REGRA DO TIMEOUT; sem idempotência, repetir às cegas cria um 2º rascunho e cobra 400 de novo (cheque action=list antes; o artigo do timeout fica salvo como rascunho).",
88
88
  schema: writeSchema,
89
89
  handler: write,
90
90
  },
@@ -99,7 +99,7 @@ export const TOOLS = {
99
99
  handler: search,
100
100
  },
101
101
  sapiens_studios: {
102
- 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
+ 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 NO AR com endereço público, sem rascunho, 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.",
103
103
  schema: studiosSchema,
104
104
  handler: studios,
105
105
  },
package/dist/skills.js CHANGED
@@ -114,6 +114,14 @@ Hedge não entra nessa lista: "ao meu ver", "por enquanto", "talvez" assinam a v
114
114
 
115
115
  Revisão é a menor edição que resolve. Corrige o tique, o erro e o trecho ilegível, e deixa em paz a frase que já funciona. Não deixa todo parágrafo igualmente arrumado, assimetria é sinal de humano. Não inventa número, exemplo nem opinião que não estava no original.
116
116
 
117
+ ## Texto que a pessoa já trouxe pronto
118
+
119
+ Vai pro perfil como está: \`sapiens_write action=create\` (title + content), de graça e sem uma linha reescrita. Depois \`action=publish\`.
120
+
121
+ Gerar com IA e sobrescrever com o original queima 400 Sinapses por nada. \`action=generate\` é pra quando ela pede pra ESCREVER, não pra publicar o que ela escreveu.
122
+
123
+ Quem tem design system (\`sapiens_brand action=list\`) já vê a capa sair na paleta dele: o \`brandSlug\` da conta veste a peça sozinho, e passar \`brandSlug\` no create troca de sistema por peça.
124
+
117
125
  ## O que manter
118
126
 
119
127
  - Léxico próprio: borderless, degen, farmei, "ombros dos gigantes", "fala ai".
@@ -276,7 +284,7 @@ Uma pessoa pode ter até 4 studios e integrar até 4. \`sapiens_studios action=m
276
284
 
277
285
  - **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
286
  - \`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.
287
+ - Nasce **no ar**, com ela como fundadora. Studio é identidade, não tem rascunho: o endereço já vale no segundo seguinte.
280
288
  - Bateu o teto de 4: o erro diz. Não insista, ela sai de um pra fundar outro.
281
289
 
282
290
  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.
@@ -68,7 +68,7 @@ export const imageSchema = z.object({
68
68
  brandSlug: z
69
69
  .string()
70
70
  .optional()
71
- .describe("Slug do brand (design system) pra aplicar estilo visual. Fonte única: tabela `brands` (ex: 'sapiens', 'solarpunk', 'editorial-duotone', 'brutalista-mono'). Default: nenhum (prompt cru). Vale em action=generate (mode=create) e request_generation."),
71
+ .describe("Slug do brand (design system) pra aplicar estilo visual. Fonte única: tabela `brands` (ex: 'sapiens', 'solarpunk', 'editorial-duotone', 'brutalista-mono'). Default: nenhum (prompt cru). NÃO herda o padrão da conta de propósito: aqui o estilo é escolha do momento, e quem só quer uma imagem pra outra coisa não deve nascer preso num visual. O padrão da pessoa (quando existe) vem em sapiens_meta action=start, campo designSystem: OFEREÇA quando a peça for da marca dela, deixe cru no resto. Vale em action=generate (mode=create) e request_generation."),
72
72
  brandMark: z
73
73
  .enum(["persona", "logo", "none"])
74
74
  .optional()
@@ -316,6 +316,19 @@ export async function meta(args) {
316
316
  : {}),
317
317
  firstPowers: FIRST_POWERS,
318
318
  startHere,
319
+ // Design system da conta: OFERTA, não default. Imagem avulsa continua
320
+ // saindo crua (quem só quer uma imagem não deve nascer preso num estilo);
321
+ // o artigo do perfil é que já herda o padrão sozinho, porque ali a peça é
322
+ // autoral por definição. Só aparece pra quem realmente tem um.
323
+ ...(who?.designSystem
324
+ ? {
325
+ designSystem: {
326
+ slug: who.designSystem.slug,
327
+ name: who.designSystem.name,
328
+ note: `O design system "${who.designSystem.name}" é o padrão da conta. Artigo do perfil já sai vestido nele. Em imagem avulsa NÃO é automático: ofereça (brandSlug="${who.designSystem.slug}") quando a peça for da marca da pessoa, e deixe cru quando ela só quer uma imagem.`,
329
+ },
330
+ }
331
+ : {}),
319
332
  moreOnDemand: "Isso é só a porta de entrada. Tem também personagens (character-lock), voz (Helen TTS), vídeo, brand/design system, comunidade, fórum e suporte. Peça 'o que mais você faz?' que eu listo, ou já manda o que você quer fazer.",
320
333
  ...(isAdmin
321
334
  ? {
@@ -19,7 +19,7 @@ export const studiosSchema = z.object({
19
19
  action: z
20
20
  .enum(["list", "get", "publishable_url", "mine", "create"])
21
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. " +
22
+ "create = FUNDA um studio novo na conta do user (exige 'name'). Nasce NO AR, com endereço público e ele como fundador (studio não tem rascunho); vestir a página é na própria página. Teto de 4 por pessoa. " +
23
23
  "list/get = catálogo de estúdios da casa. publishable_url = URL de artigo."),
24
24
  studio: z
25
25
  .string()
@@ -229,7 +229,7 @@ export async function studios(args) {
229
229
  });
230
230
  return {
231
231
  ...res,
232
- note: "Studio fundado, privado por enquanto. O user publica e veste a página (capa, logo, sobre, time, obra) em " +
232
+ note: "Studio fundado e NO AR nesse endereço. O user veste a página (capa, logo, sobre, time, obra) em " +
233
233
  `${APP}/studios/${res.slug} no modo edição. Convidar gente exige follow mútuo.`,
234
234
  };
235
235
  }
@@ -9,6 +9,9 @@ import { convexQuery, convexMutation, convexAction, getSessionToken, } from "../
9
9
  * /u/<username>), gastando as Sinapses dele. Identidade vem do sessionToken.
10
10
  *
11
11
  * Sub-actions:
12
+ * - create: salva um texto que VOCÊ já escreveu. De graça, sem IA no caminho.
13
+ * É a porta certa pra "publica esse meu artigo": gerar e depois sobrescrever
14
+ * com o original queima 400 Sinapses à toa.
12
15
  * - generate: gera 1 artigo na voz Sapiens a partir de um brief livre
13
16
  * (ou reescrevendo um artigo publicado / um texto teu). Cobra 400 Sinapses,
14
17
  * reembolsa se a geração falhar. Salva como rascunho no teu perfil.
@@ -18,12 +21,26 @@ import { convexQuery, convexMutation, convexAction, getSessionToken, } from "../
18
21
  * - publish: publica no teu perfil (publish=true) ou volta pra rascunho (false).
19
22
  */
20
23
  export const writeSchema = z.object({
21
- action: z.enum(["generate", "list", "get", "update", "publish"]),
24
+ action: z.enum(["create", "generate", "list", "get", "update", "publish"]),
25
+ // --- create (texto pronto, GRÁTIS) ---
26
+ // title/content são compartilhados com update (declarados lá embaixo).
27
+ category: z
28
+ .string()
29
+ .optional()
30
+ .describe("create: categoria do artigo (ex: 'filosofia-tech'). Opcional."),
31
+ tags: z
32
+ .array(z.string())
33
+ .optional()
34
+ .describe("create: até 8 tags específicas. Opcional."),
35
+ brandSlug: z
36
+ .string()
37
+ .optional()
38
+ .describe("create: design system que veste a peça (slug via sapiens_brand action=list). Omitido, herda o padrão da tua conta. É o que faz a capa e as imagens saírem no TEU estilo, não no da casa."),
22
39
  // --- generate ---
23
40
  brief: z
24
41
  .string()
25
42
  .optional()
26
- .describe("Briefing livre (1 parágrafo, até ~600 palavras). Caminho padrão de 'generate'. A IA expande na voz Sapiens. Custa 400 Sinapses."),
43
+ .describe("Briefing livre (1 parágrafo, até ~600 palavras). Caminho padrão de 'generate'. A IA expande na voz Sapiens. Custa 400 Sinapses. Pra texto que VOCÊ já escreveu, use action=create (de graça)."),
27
44
  sourceKind: z
28
45
  .enum(["brief", "published_article", "user_article"])
29
46
  .optional()
@@ -56,7 +73,7 @@ export const writeSchema = z.object({
56
73
  coverImageId: z
57
74
  .string()
58
75
  .optional()
59
- .describe("Capa PRONTA (opcional, generate): id de uma imagem da TUA galeria (generatedImages:_id, ache via sapiens_gallery/sapiens_reference) que vira a capa do artigo em vez da capa-cortesia gerada do zero. Use quando você JÁ gerou a imagem (sapiens_image) e o artigo é sobre ela assim a peça não nasce sem capa se a cortesia falhar."),
76
+ .describe("Capa PRONTA (opcional, vale em create e generate): id de uma imagem da TUA galeria (generatedImages:_id, ache via sapiens_gallery/sapiens_reference) que vira a capa do artigo em vez da capa-cortesia gerada do zero. Use quando você JÁ gerou a imagem (sapiens_image) e o artigo é sobre ela: assim a peça não nasce sem capa se a cortesia falhar."),
60
77
  coverImageUrl: httpUrl()
61
78
  .optional()
62
79
  .describe("Alternativa a coverImageId: URL de imagem do Sapiens (Bunny CDN / Convex) pra usar como capa pronta. Host fora da allowlist é recusado."),
@@ -73,12 +90,15 @@ export const writeSchema = z.object({
73
90
  .string()
74
91
  .optional()
75
92
  .describe("user_articles:_id (obrigatório pra get/update/publish)."),
76
- // --- update ---
77
- title: z.string().optional(),
93
+ // --- create / update ---
94
+ title: z
95
+ .string()
96
+ .optional()
97
+ .describe("Obrigatório em create. Em update, renomeia."),
78
98
  content: z
79
99
  .string()
80
100
  .optional()
81
- .describe("Markdown completo do corpo (substitui o conteúdo)."),
101
+ .describe("Markdown completo do corpo. Em create, é o teu texto na íntegra (nada é reescrito). Em update, substitui o conteúdo."),
82
102
  excerpt: z.string().optional(),
83
103
  tldr: z.string().optional(),
84
104
  // --- publish ---
@@ -89,6 +109,27 @@ export const writeSchema = z.object({
89
109
  });
90
110
  export async function write(args) {
91
111
  const sessionToken = getSessionToken();
112
+ if (args.action === "create") {
113
+ if (!args.title?.trim()) {
114
+ throw new Error("action=create exige title (o texto é teu, então o título também).");
115
+ }
116
+ const res = await convexMutation("mcpExtras:mcpUserCreateArticle", {
117
+ sessionToken,
118
+ title: args.title,
119
+ content: args.content,
120
+ excerpt: args.excerpt,
121
+ tldr: args.tldr,
122
+ category: args.category,
123
+ tags: args.tags,
124
+ brandSlug: args.brandSlug,
125
+ coverImageId: args.coverImageId,
126
+ coverImageUrl: args.coverImageUrl,
127
+ });
128
+ return {
129
+ ...res,
130
+ note: "Salvo como RASCUNHO, sem custo e sem uma linha reescrita. Pra ir ao ar no perfil: action=publish com este articleId.",
131
+ };
132
+ }
92
133
  if (args.action === "generate") {
93
134
  const sourceKind = args.sourceKind ?? "brief";
94
135
  if (sourceKind === "brief" &&
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sapiens-mcp",
3
- "version": "1.46.3",
3
+ "version": "1.46.5",
4
4
  "mcpName": "com.sapiensinteticos/sapiens",
5
5
  "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.",
6
6
  "type": "module",