sapiens-mcp 1.59.1 → 1.61.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/dist/registry.js +10 -0
- package/dist/tools/character.js +15 -3
- package/dist/tools/distribution.js +134 -0
- package/package.json +1 -1
package/dist/registry.js
CHANGED
|
@@ -35,6 +35,7 @@ import { publicidade, publicidadeSchema } from "./tools/publicidade.js";
|
|
|
35
35
|
import { reference, referenceSchema } from "./tools/reference.js";
|
|
36
36
|
import { trilhas, trilhasSchema } from "./tools/trilhas.js";
|
|
37
37
|
import { semana, semanaSchema } from "./tools/semana.js";
|
|
38
|
+
import { distribution, distributionSchema } from "./tools/distribution.js";
|
|
38
39
|
import { shareDrop, shareDropSchema } from "./tools/shareDrop.js";
|
|
39
40
|
import { skill, skillSchema } from "./tools/skill.js";
|
|
40
41
|
import { resume, resumeSchema } from "./tools/resume.js";
|
|
@@ -203,6 +204,11 @@ export const TOOLS = {
|
|
|
203
204
|
schema: trilhasSchema,
|
|
204
205
|
handler: trilhas,
|
|
205
206
|
},
|
|
207
|
+
sapiens_distribution: {
|
|
208
|
+
description: "Despachar peças (Distribution Workflow) — a peça pronta entra na FILA com canal, copy e a aba de quem ela é. ADMIN-ONLY: despacho depende de rede conectada e hoje só a casa tem. NADA aqui posta em rede nenhuma; quem despacha é a tela em /experimentos/distribution-workflow, que é onde a conta conectada mora. A ABA (`voice`) responde de quem é a peça: sapiens (a casa), helen-ailith, borderless, ou o slug de um personagem seu — slug livre, então personagem novo ganha aba sozinho na primeira peça dele, sem deploy. Em queue, aba ausente = o servidor deriva do personagem da peça e cai em sapiens quando não há. Sub-actions: queue (põe na fila: title e channel obrigatórios, mais copy/hashtags/assetUrl/notes), list (o que está na fila, filtrável por status e por aba), voices (as abas que existem hoje com a contagem de cada uma), status (move a peça de lane: fila, agendado, postado, descartado; postado aceita postUrl e fecha o rastro, agendado aceita scheduledFor em ms). Sem custo em Sinapses: isto organiza, não gera. A copy segue a voz de QUEM ASSINA a peça, que não é sempre a voz da casa: peça da Helen fala como a Helen.",
|
|
209
|
+
schema: distributionSchema,
|
|
210
|
+
handler: distribution,
|
|
211
|
+
},
|
|
206
212
|
sapiens_semana: {
|
|
207
213
|
description: "As Atividades da SUA semana na casa: o que você produziu e quanto XP isso rendeu. Identidade SEMPRE pelo sessionToken. Sub-actions: 'get' (quais atividades você fez nesta semana, quantas peças em cada, o XP já pago, quanto a Casa Cheia renderia no fecho, quanto vale abrir mais uma atividade e QUAIS abrir agora, a sequência de semanas seguidas com o recorde, as semanas anteriores com o que cada uma rendeu, e uma leitura pronta da semana pra você dizer em voz alta), 'fechar' (fecha as semanas pendentes e credita a Casa Cheia de cada uma). Como a régua funciona: cada peça pronta anda o contador da atividade e paga em degraus (1a, 3a, 7a, 15a, 30a peça da semana, com retorno decrescente); no fecho, a LARGURA paga à parte, 2 atividades valem 20 XP, 5 valem 200, 8 valem 560, então atividades diferentes rendem mais que repetir a mesma. Esta tool PAGA XP, não cobra Sinapses. Idempotente: chamar 'fechar' duas vezes não credita duas vezes.",
|
|
208
214
|
schema: semanaSchema,
|
|
@@ -294,6 +300,7 @@ const TOOL_TITLES = {
|
|
|
294
300
|
sapiens_atlas: "Atlas Ecossistema IA",
|
|
295
301
|
sapiens_reference: "Referências",
|
|
296
302
|
sapiens_trilhas: "Trilhas & Desafios",
|
|
303
|
+
sapiens_distribution: "Despachar peças",
|
|
297
304
|
sapiens_semana: "Minha Semana",
|
|
298
305
|
sapiens_instagram: "Auto-DM Instagram",
|
|
299
306
|
sapiens_share: "Share Drop",
|
|
@@ -314,6 +321,9 @@ const ADMIN_ONLY_TOOLS = new Set([
|
|
|
314
321
|
"sapiens_share",
|
|
315
322
|
"sapiens_decupagem",
|
|
316
323
|
"sapiens_publicidade",
|
|
324
|
+
// Despacho depende de rede conectada, e hoje so a casa tem: a rota tambem e
|
|
325
|
+
// adminOnly. Quando abrir pra membro, sai daqui e do gate da rota juntos.
|
|
326
|
+
"sapiens_distribution",
|
|
317
327
|
]);
|
|
318
328
|
/**
|
|
319
329
|
* Monta o payload do tools/list pro tier dado. Tier "user" esconde as
|
package/dist/tools/character.js
CHANGED
|
@@ -46,7 +46,8 @@ import { convexQuery, convexMutation, convexAction, getSessionToken } from "../c
|
|
|
46
46
|
* gente pede o arg no create; quem já existe sem ele conserta com set_card.
|
|
47
47
|
*
|
|
48
48
|
* O TRAÇO (`style`) é em que TÉCNICA ele é feito: auto (default), realista,
|
|
49
|
-
* editorial (o cartum adulto da casa), anime, manhwa,
|
|
49
|
+
* editorial (o cartum adulto da casa), anime, manhwa, concept (mídia
|
|
50
|
+
* tradicional suja, o traço de criatura), 3d, custom. É o
|
|
50
51
|
* vocabulário da CASA (convex/shared/visualStyle.ts), o mesmo que o Reflexo de
|
|
51
52
|
* Si lê. As três peças do personagem leem daqui pra saber se estão
|
|
52
53
|
* fazendo foto, desenho ou render. No automático a peça não afirma técnica
|
|
@@ -132,12 +133,23 @@ export const characterSchema = z.object({
|
|
|
132
133
|
"pra decidir se descrevem rosto e mãos ou silhueta e postura, e sem isso o " +
|
|
133
134
|
"modelo desenha uma pessoa em cima da criatura. Ausente no create = human."),
|
|
134
135
|
style: z
|
|
135
|
-
.enum([
|
|
136
|
+
.enum([
|
|
137
|
+
"auto",
|
|
138
|
+
"realista",
|
|
139
|
+
"editorial",
|
|
140
|
+
"anime",
|
|
141
|
+
"manhwa",
|
|
142
|
+
"concept",
|
|
143
|
+
"3d",
|
|
144
|
+
"custom",
|
|
145
|
+
])
|
|
136
146
|
.optional()
|
|
137
147
|
.describe("Pra create/set_card: em que TÉCNICA o personagem é feito. 'auto' (default) " +
|
|
138
148
|
"não afirma técnica nenhuma e deixa as imagens de referência mandarem; " +
|
|
139
149
|
"'realista' é fotografia (óptica, luz e pele reais); 'anime' é cel shading " +
|
|
140
|
-
"com contorno de tinta; 'manhwa' é pintura digital suave de webtoon;
|
|
150
|
+
"com contorno de tinta; 'manhwa' é pintura digital suave de webtoon; " +
|
|
151
|
+
"'concept' é mídia tradicional suja, grafite e aguada sobre papel, o " +
|
|
152
|
+
"traço de criatura e bestiário; '3d' é " +
|
|
141
153
|
"render com material e oclusão; 'custom' usa a linha escrita em styleNote. " +
|
|
142
154
|
"Irmão de `form`, e a divisão é limpa: a forma diz que CORPO é esse, o traço " +
|
|
143
155
|
"diz como ele é DESENHADO. Mande sempre que o personagem tiver técnica " +
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { convexQuery, convexMutation, getSessionToken } from "../convexClient.js";
|
|
3
|
+
/**
|
|
4
|
+
* sapiens_distribution: o Despachar peças pelo agente.
|
|
5
|
+
*
|
|
6
|
+
* A peça pronta (imagem, vídeo, carrossel, artigo) entra na FILA do Distribution
|
|
7
|
+
* Workflow com canal, copy e a aba de quem ela é. Nada aqui posta em rede
|
|
8
|
+
* nenhuma: quem despacha continua sendo a tela, porque é lá que mora a conta
|
|
9
|
+
* conectada. O que a tool faz é tirar o trabalho de digitar peça por peça.
|
|
10
|
+
*
|
|
11
|
+
* ADMIN-ONLY de propósito. A rota /experimentos/distribution-workflow também é:
|
|
12
|
+
* despacho depende de rede conectada e hoje só a casa tem. Membro que chamar
|
|
13
|
+
* recebe o recado do servidor, não uma tela vazia.
|
|
14
|
+
*
|
|
15
|
+
* A ABA (`voice`) é de quem é a peça: `sapiens` (a casa), `helen-ailith`,
|
|
16
|
+
* `borderless`, ou o slug de um personagem novo. Slug livre: personagem novo
|
|
17
|
+
* ganha aba sozinho quando a primeira peça dele é despachada. Ausente, o
|
|
18
|
+
* servidor deriva do personagem da peça e cai em `sapiens` quando não há.
|
|
19
|
+
*
|
|
20
|
+
* Sub-actions:
|
|
21
|
+
* - queue: põe uma peça na fila (title + channel obrigatórios).
|
|
22
|
+
* - list: o que está na fila, filtrável por status e por aba.
|
|
23
|
+
* - voices: as abas que existem hoje, com a contagem de cada uma.
|
|
24
|
+
* - status: move a peça de lane (fila, agendado, postado, descartado).
|
|
25
|
+
*
|
|
26
|
+
* Sem custo em Sinapses: isto organiza, não gera.
|
|
27
|
+
*/
|
|
28
|
+
const CHANNELS = [
|
|
29
|
+
"instagram",
|
|
30
|
+
"youtube",
|
|
31
|
+
"x",
|
|
32
|
+
"tiktok",
|
|
33
|
+
"threads",
|
|
34
|
+
"linkedin",
|
|
35
|
+
"google-business",
|
|
36
|
+
"bluesky",
|
|
37
|
+
"farcaster",
|
|
38
|
+
"telegram",
|
|
39
|
+
"reddit",
|
|
40
|
+
"medium",
|
|
41
|
+
"pinterest",
|
|
42
|
+
];
|
|
43
|
+
export const distributionSchema = z.object({
|
|
44
|
+
action: z.enum(["queue", "list", "voices", "status"]),
|
|
45
|
+
title: z
|
|
46
|
+
.string()
|
|
47
|
+
.optional()
|
|
48
|
+
.describe("queue: título INTERNO da peça (como você a acha na lista). Obrigatório."),
|
|
49
|
+
channel: z
|
|
50
|
+
.enum(CHANNELS)
|
|
51
|
+
.optional()
|
|
52
|
+
.describe("queue: o canal de destino. Obrigatório."),
|
|
53
|
+
copy: z
|
|
54
|
+
.string()
|
|
55
|
+
.optional()
|
|
56
|
+
.describe("queue: a legenda pronta pra colar, na voz de quem assina a peça. Sem em-dash."),
|
|
57
|
+
hashtags: z.array(z.string()).optional().describe("queue: sem o #, o servidor limpa."),
|
|
58
|
+
assetUrl: z
|
|
59
|
+
.string()
|
|
60
|
+
.optional()
|
|
61
|
+
.describe("queue: a mídia da peça (URL de host Sapiens, a que sapiens_image/sapiens_gallery devolvem)."),
|
|
62
|
+
assetKind: z.enum(["image", "video", "audio"]).optional(),
|
|
63
|
+
voice: z
|
|
64
|
+
.string()
|
|
65
|
+
.optional()
|
|
66
|
+
.describe("A aba de quem é a peça: sapiens, helen-ailith, borderless, ou o slug de um personagem seu. Em queue, ausente = o servidor deriva. Em list, filtra."),
|
|
67
|
+
notes: z.string().optional().describe("queue: recado pra você mesmo na hora de postar."),
|
|
68
|
+
itemId: z.string().optional().describe("status: o id da peça (vem do list ou do queue)."),
|
|
69
|
+
status: z
|
|
70
|
+
.enum(["fila", "agendado", "postado", "descartado"])
|
|
71
|
+
.optional()
|
|
72
|
+
.describe("list: filtra a lane. status: a lane pra onde a peça vai."),
|
|
73
|
+
postUrl: z
|
|
74
|
+
.string()
|
|
75
|
+
.optional()
|
|
76
|
+
.describe("status=postado: o link do post que foi ao ar, pro rastro fechar."),
|
|
77
|
+
scheduledFor: z
|
|
78
|
+
.number()
|
|
79
|
+
.optional()
|
|
80
|
+
.describe("status=agendado: timestamp em ms de quando ela sai."),
|
|
81
|
+
limit: z.number().int().positive().max(60).optional().describe("list: default 20."),
|
|
82
|
+
});
|
|
83
|
+
export async function distribution(args) {
|
|
84
|
+
const sessionToken = getSessionToken();
|
|
85
|
+
if (args.action === "queue") {
|
|
86
|
+
if (!args.title)
|
|
87
|
+
throw new Error("action=queue exige title.");
|
|
88
|
+
if (!args.channel)
|
|
89
|
+
throw new Error("action=queue exige channel.");
|
|
90
|
+
const r = await convexMutation("distributionMcp:mcpQueueItem", {
|
|
91
|
+
sessionToken,
|
|
92
|
+
title: args.title,
|
|
93
|
+
channel: args.channel,
|
|
94
|
+
copy: args.copy,
|
|
95
|
+
hashtags: args.hashtags,
|
|
96
|
+
assetUrl: args.assetUrl,
|
|
97
|
+
assetKind: args.assetKind,
|
|
98
|
+
voice: args.voice,
|
|
99
|
+
notes: args.notes,
|
|
100
|
+
});
|
|
101
|
+
return {
|
|
102
|
+
itemId: r.itemId,
|
|
103
|
+
status: "fila",
|
|
104
|
+
voice: args.voice ?? "(derivado no servidor)",
|
|
105
|
+
instruction: "A peça está na fila do Distribution Workflow, não foi ao ar. Quem posta é a tela, em /experimentos/distribution-workflow.",
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
if (args.action === "list") {
|
|
109
|
+
return await convexQuery("distributionMcp:mcpListItems", {
|
|
110
|
+
sessionToken,
|
|
111
|
+
status: args.status,
|
|
112
|
+
voice: args.voice,
|
|
113
|
+
limit: args.limit,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
if (args.action === "voices") {
|
|
117
|
+
return await convexQuery("distributionMcp:mcpVoices", { sessionToken });
|
|
118
|
+
}
|
|
119
|
+
if (args.action === "status") {
|
|
120
|
+
if (!args.itemId)
|
|
121
|
+
throw new Error("action=status exige itemId.");
|
|
122
|
+
if (!args.status)
|
|
123
|
+
throw new Error("action=status exige status.");
|
|
124
|
+
await convexMutation("distributionMcp:mcpSetStatus", {
|
|
125
|
+
sessionToken,
|
|
126
|
+
itemId: args.itemId,
|
|
127
|
+
status: args.status,
|
|
128
|
+
postUrl: args.postUrl,
|
|
129
|
+
scheduledFor: args.scheduledFor,
|
|
130
|
+
});
|
|
131
|
+
return { ok: true, itemId: args.itemId, status: args.status };
|
|
132
|
+
}
|
|
133
|
+
throw new Error(`action desconhecida: ${args.action}`);
|
|
134
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sapiens-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.61.0",
|
|
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",
|