beplus-mcp 0.26.0 → 0.27.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/README.md +7 -0
- package/dist/index.js +388 -58
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -916,10 +916,10 @@ var require_codegen = __commonJS({
|
|
|
916
916
|
return this._leafNode(new Throw(error2));
|
|
917
917
|
}
|
|
918
918
|
// start self-balancing block
|
|
919
|
-
block(
|
|
919
|
+
block(body2, nodeCount) {
|
|
920
920
|
this._blockStarts.push(this._nodes.length);
|
|
921
|
-
if (
|
|
922
|
-
this.code(
|
|
921
|
+
if (body2)
|
|
922
|
+
this.code(body2).endBlock(nodeCount);
|
|
923
923
|
return this;
|
|
924
924
|
}
|
|
925
925
|
// end the current self-balancing block
|
|
@@ -2344,15 +2344,15 @@ var require_validate = __commonJS({
|
|
|
2344
2344
|
validateFunction(it, () => (0, boolSchema_1.topBoolOrEmptySchema)(it));
|
|
2345
2345
|
}
|
|
2346
2346
|
exports.validateFunctionCode = validateFunctionCode;
|
|
2347
|
-
function validateFunction({ gen, validateName, schema, schemaEnv, opts },
|
|
2347
|
+
function validateFunction({ gen, validateName, schema, schemaEnv, opts }, body2) {
|
|
2348
2348
|
if (opts.code.es5) {
|
|
2349
2349
|
gen.func(validateName, (0, codegen_1._)`${names_1.default.data}, ${names_1.default.valCxt}`, schemaEnv.$async, () => {
|
|
2350
2350
|
gen.code((0, codegen_1._)`"use strict"; ${funcSourceUrl(schema, opts)}`);
|
|
2351
2351
|
destructureValCxtES5(gen, opts);
|
|
2352
|
-
gen.code(
|
|
2352
|
+
gen.code(body2);
|
|
2353
2353
|
});
|
|
2354
2354
|
} else {
|
|
2355
|
-
gen.func(validateName, (0, codegen_1._)`${names_1.default.data}, ${destructureValCxt(opts)}`, schemaEnv.$async, () => gen.code(funcSourceUrl(schema, opts)).code(
|
|
2355
|
+
gen.func(validateName, (0, codegen_1._)`${names_1.default.data}, ${destructureValCxt(opts)}`, schemaEnv.$async, () => gen.code(funcSourceUrl(schema, opts)).code(body2));
|
|
2356
2356
|
}
|
|
2357
2357
|
}
|
|
2358
2358
|
function destructureValCxt(opts) {
|
|
@@ -21156,11 +21156,11 @@ var EMPTY_COMPLETION_RESULT = {
|
|
|
21156
21156
|
var ApiError = class extends Error {
|
|
21157
21157
|
httpStatus;
|
|
21158
21158
|
body;
|
|
21159
|
-
constructor(httpStatus, message,
|
|
21159
|
+
constructor(httpStatus, message, body2) {
|
|
21160
21160
|
super(message);
|
|
21161
21161
|
this.name = "ApiError";
|
|
21162
21162
|
this.httpStatus = httpStatus;
|
|
21163
|
-
this.body =
|
|
21163
|
+
this.body = body2;
|
|
21164
21164
|
}
|
|
21165
21165
|
};
|
|
21166
21166
|
function apiErrorToUserMessage(err) {
|
|
@@ -21244,14 +21244,14 @@ var BeplusClient = class {
|
|
|
21244
21244
|
}
|
|
21245
21245
|
return json2 && typeof json2 === "object" && "result" in json2 ? json2.result : json2;
|
|
21246
21246
|
}
|
|
21247
|
-
startGeneration(
|
|
21248
|
-
return this.request("POST", "/generations", { body });
|
|
21247
|
+
startGeneration(body2) {
|
|
21248
|
+
return this.request("POST", "/generations", { body: body2 });
|
|
21249
21249
|
}
|
|
21250
21250
|
listProjects() {
|
|
21251
21251
|
return this.request("GET", "/projects");
|
|
21252
21252
|
}
|
|
21253
|
-
createProject(
|
|
21254
|
-
return this.request("POST", "/projects", { body });
|
|
21253
|
+
createProject(body2) {
|
|
21254
|
+
return this.request("POST", "/projects", { body: body2 });
|
|
21255
21255
|
}
|
|
21256
21256
|
getActiveProject() {
|
|
21257
21257
|
return this.request("GET", "/projects/active");
|
|
@@ -21263,8 +21263,8 @@ var BeplusClient = class {
|
|
|
21263
21263
|
listClients() {
|
|
21264
21264
|
return this.request("GET", "/clients");
|
|
21265
21265
|
}
|
|
21266
|
-
createClient(
|
|
21267
|
-
return this.request("POST", "/clients", { body });
|
|
21266
|
+
createClient(body2) {
|
|
21267
|
+
return this.request("POST", "/clients", { body: body2 });
|
|
21268
21268
|
}
|
|
21269
21269
|
setActiveClient(client) {
|
|
21270
21270
|
return this.request("PUT", "/clients/active", { body: { client } });
|
|
@@ -21286,8 +21286,8 @@ var BeplusClient = class {
|
|
|
21286
21286
|
}
|
|
21287
21287
|
});
|
|
21288
21288
|
}
|
|
21289
|
-
tts(
|
|
21290
|
-
return this.request("POST", "/tts", { body, timeoutMs: 9e4 });
|
|
21289
|
+
tts(body2) {
|
|
21290
|
+
return this.request("POST", "/tts", { body: body2, timeoutMs: 9e4 });
|
|
21291
21291
|
}
|
|
21292
21292
|
models() {
|
|
21293
21293
|
return this.request("GET", "/models");
|
|
@@ -21302,11 +21302,11 @@ var BeplusClient = class {
|
|
|
21302
21302
|
me(billing) {
|
|
21303
21303
|
return this.request("GET", "/me", { query: { billing } });
|
|
21304
21304
|
}
|
|
21305
|
-
readProvenance(
|
|
21306
|
-
return this.request("POST", "/read-provenance", { body, timeoutMs: 3e4 });
|
|
21305
|
+
readProvenance(body2) {
|
|
21306
|
+
return this.request("POST", "/read-provenance", { body: body2, timeoutMs: 3e4 });
|
|
21307
21307
|
}
|
|
21308
|
-
analyzeMedia(
|
|
21309
|
-
return this.request("POST", "/analyze-media", { body, timeoutMs: 3e5 });
|
|
21308
|
+
analyzeMedia(body2) {
|
|
21309
|
+
return this.request("POST", "/analyze-media", { body: body2, timeoutMs: 3e5 });
|
|
21310
21310
|
}
|
|
21311
21311
|
searchCalls(query) {
|
|
21312
21312
|
return this.request("GET", "/calls", {
|
|
@@ -22874,7 +22874,7 @@ function registerAudioTools(server, client, cfg) {
|
|
|
22874
22874
|
},
|
|
22875
22875
|
async (args) => {
|
|
22876
22876
|
try {
|
|
22877
|
-
const
|
|
22877
|
+
const body2 = compact({
|
|
22878
22878
|
text: args.text,
|
|
22879
22879
|
voice: args.voice,
|
|
22880
22880
|
model: args.model,
|
|
@@ -22882,7 +22882,7 @@ function registerAudioTools(server, client, cfg) {
|
|
|
22882
22882
|
multiSpeaker: args.multi_speaker,
|
|
22883
22883
|
project: args.project ?? cfg.activeProject ?? void 0
|
|
22884
22884
|
});
|
|
22885
|
-
const res = await client.tts(
|
|
22885
|
+
const res = await client.tts(body2);
|
|
22886
22886
|
const parts = [`Custo: ${res.diamond_cost} \u{1F48E}`];
|
|
22887
22887
|
if (res.diamonds_refunded) parts.push(`Estorno: ${res.diamonds_refunded} \u{1F48E}`);
|
|
22888
22888
|
const projLine = res.project_code ? `
|
|
@@ -23378,11 +23378,11 @@ function fmtDate(iso) {
|
|
|
23378
23378
|
function callLine(c) {
|
|
23379
23379
|
const company = c.company_name ? ` \xB7 ${c.company_name}` : "";
|
|
23380
23380
|
const proj = c.project_name ? ` \xB7 ${c.client_name ? c.client_name + " / " : ""}${c.project_name}` : "";
|
|
23381
|
-
const
|
|
23381
|
+
const who2 = c.speakers.length ? ` \xB7 ${c.speakers.join(", ")}` : c.participant_count ? ` \xB7 ${c.participant_count} falantes` : "";
|
|
23382
23382
|
const vis = VIS_LABEL[c.visibility] ?? c.visibility;
|
|
23383
23383
|
const flag = c.status !== "ready" ? ` [${c.status}]` : "";
|
|
23384
23384
|
return `\u2022 ${c.title ?? "(sem t\xEDtulo)"}${flag}
|
|
23385
|
-
${fmtDate(c.date)} \xB7 ${fmtDuration(c.duration_sec)} \xB7 ${vis}${company}${proj}${
|
|
23385
|
+
${fmtDate(c.date)} \xB7 ${fmtDuration(c.duration_sec)} \xB7 ${vis}${company}${proj}${who2}
|
|
23386
23386
|
id: ${c.id}`;
|
|
23387
23387
|
}
|
|
23388
23388
|
function renderCall(c) {
|
|
@@ -23475,6 +23475,12 @@ function errorRaw(err) {
|
|
|
23475
23475
|
const raw = err.body?.error?.raw;
|
|
23476
23476
|
return raw && typeof raw === "object" ? raw : void 0;
|
|
23477
23477
|
}
|
|
23478
|
+
var commentPacing = {
|
|
23479
|
+
perMinute: 50,
|
|
23480
|
+
retryWaitsMs: [5e3, 15e3, 45e3],
|
|
23481
|
+
now: () => Date.now(),
|
|
23482
|
+
sleep: (ms) => new Promise((r) => setTimeout(r, Math.max(0, ms)))
|
|
23483
|
+
};
|
|
23478
23484
|
var CanvasApi = class {
|
|
23479
23485
|
constructor(client, cfg) {
|
|
23480
23486
|
this.client = client;
|
|
@@ -23484,6 +23490,8 @@ var CanvasApi = class {
|
|
|
23484
23490
|
cfg;
|
|
23485
23491
|
coreVersion = PINNED_CORE_VERSION;
|
|
23486
23492
|
userId = null;
|
|
23493
|
+
/** Instantes das escritas de comentário no último minuto. */
|
|
23494
|
+
writes = [];
|
|
23487
23495
|
req(method, path, opts = {}) {
|
|
23488
23496
|
return this.client.request(method, path, { ...opts, base: this.cfg.canvasBase });
|
|
23489
23497
|
}
|
|
@@ -23499,16 +23507,16 @@ var CanvasApi = class {
|
|
|
23499
23507
|
listBoards(kind = "board") {
|
|
23500
23508
|
return this.req("GET", "/boards", { query: { kind } });
|
|
23501
23509
|
}
|
|
23502
|
-
createBoard(
|
|
23503
|
-
return this.req("POST", "/boards", { body });
|
|
23510
|
+
createBoard(body2) {
|
|
23511
|
+
return this.req("POST", "/boards", { body: body2 });
|
|
23504
23512
|
}
|
|
23505
|
-
snapshot(
|
|
23506
|
-
return this.req("GET", `/boards/${
|
|
23513
|
+
snapshot(boardId3) {
|
|
23514
|
+
return this.req("GET", `/boards/${boardId3}`);
|
|
23507
23515
|
}
|
|
23508
23516
|
/** Replay depois de `after`. `null` quando o servidor manda reler a foto (410). */
|
|
23509
|
-
async opsAfter(
|
|
23517
|
+
async opsAfter(boardId3, after) {
|
|
23510
23518
|
try {
|
|
23511
|
-
const { envelopes } = await this.req("GET", `/boards/${
|
|
23519
|
+
const { envelopes } = await this.req("GET", `/boards/${boardId3}/ops`, {
|
|
23512
23520
|
query: { after }
|
|
23513
23521
|
});
|
|
23514
23522
|
return envelopes;
|
|
@@ -23517,8 +23525,8 @@ var CanvasApi = class {
|
|
|
23517
23525
|
throw e;
|
|
23518
23526
|
}
|
|
23519
23527
|
}
|
|
23520
|
-
async commit(
|
|
23521
|
-
const send = () => this.req("POST", `/boards/${
|
|
23528
|
+
async commit(boardId3, ops) {
|
|
23529
|
+
const send = () => this.req("POST", `/boards/${boardId3}/ops`, {
|
|
23522
23530
|
body: { coreVersion: this.coreVersion, ops }
|
|
23523
23531
|
});
|
|
23524
23532
|
try {
|
|
@@ -23539,14 +23547,51 @@ var CanvasApi = class {
|
|
|
23539
23547
|
}
|
|
23540
23548
|
}
|
|
23541
23549
|
}
|
|
23542
|
-
members(
|
|
23543
|
-
return this.req("GET", `/boards/${
|
|
23550
|
+
members(boardId3) {
|
|
23551
|
+
return this.req("GET", `/boards/${boardId3}/members`);
|
|
23552
|
+
}
|
|
23553
|
+
putMember(boardId3, userId, role) {
|
|
23554
|
+
return this.req("PUT", `/boards/${boardId3}/members/${userId}`, { body: { role } });
|
|
23544
23555
|
}
|
|
23545
|
-
|
|
23546
|
-
return this.req("
|
|
23556
|
+
removeMember(boardId3, userId) {
|
|
23557
|
+
return this.req("DELETE", `/boards/${boardId3}/members/${userId}`);
|
|
23547
23558
|
}
|
|
23548
|
-
|
|
23549
|
-
|
|
23559
|
+
// ── comentários (academy-backend #313) ────────────────────────────────────
|
|
23560
|
+
listComments(boardId3, status = "open") {
|
|
23561
|
+
return this.req("GET", `/boards/${boardId3}/comments`, { query: { status } });
|
|
23562
|
+
}
|
|
23563
|
+
/**
|
|
23564
|
+
* Escrita de comentário passa por aqui: o back limita a 60 por minuto por pessoa
|
|
23565
|
+
* (balde fixo, sem Retry-After). O MCP se espaça abaixo do teto e, se ainda
|
|
23566
|
+
* assim vier 429 (a pessoa também comentando no Canvas), espera e tenta de novo.
|
|
23567
|
+
*/
|
|
23568
|
+
async write(method, path, body2) {
|
|
23569
|
+
const p = commentPacing;
|
|
23570
|
+
const now = p.now();
|
|
23571
|
+
this.writes = this.writes.filter((t) => now - t < 6e4);
|
|
23572
|
+
if (this.writes.length >= p.perMinute) {
|
|
23573
|
+
await p.sleep(this.writes[0] + 6e4 - now);
|
|
23574
|
+
this.writes.shift();
|
|
23575
|
+
}
|
|
23576
|
+
for (let attempt = 0; ; attempt++) {
|
|
23577
|
+
this.writes.push(p.now());
|
|
23578
|
+
try {
|
|
23579
|
+
return await this.req(method, path, body2 === void 0 ? {} : { body: body2 });
|
|
23580
|
+
} catch (e) {
|
|
23581
|
+
if (!(e instanceof ApiError) || e.httpStatus !== 429 || attempt >= p.retryWaitsMs.length) throw e;
|
|
23582
|
+
await p.sleep(p.retryWaitsMs[attempt]);
|
|
23583
|
+
}
|
|
23584
|
+
}
|
|
23585
|
+
}
|
|
23586
|
+
/** Raiz ou resposta. O back devolve sempre a THREAD DA RAIZ (resposta nova = última de `replies`). */
|
|
23587
|
+
createComment(boardId3, body2) {
|
|
23588
|
+
return this.write("POST", `/boards/${boardId3}/comments`, body2);
|
|
23589
|
+
}
|
|
23590
|
+
resolveComment(boardId3, commentId2) {
|
|
23591
|
+
return this.write("POST", `/boards/${boardId3}/comments/${commentId2}/resolve`);
|
|
23592
|
+
}
|
|
23593
|
+
reopenComment(boardId3, commentId2) {
|
|
23594
|
+
return this.write("POST", `/boards/${boardId3}/comments/${commentId2}/reopen`);
|
|
23550
23595
|
}
|
|
23551
23596
|
/** Só para os testes conferirem o aprendizado. */
|
|
23552
23597
|
get currentCoreVersion() {
|
|
@@ -23563,6 +23608,8 @@ var CoreMismatchError = class extends Error {
|
|
|
23563
23608
|
}
|
|
23564
23609
|
serverVersion;
|
|
23565
23610
|
};
|
|
23611
|
+
var CanvasToolError = class extends Error {
|
|
23612
|
+
};
|
|
23566
23613
|
|
|
23567
23614
|
// src/canvas/catalog.ts
|
|
23568
23615
|
var WORKFLOW_NODE_TYPE = "workflow";
|
|
@@ -23816,8 +23863,8 @@ function checkOp(op) {
|
|
|
23816
23863
|
return null;
|
|
23817
23864
|
}
|
|
23818
23865
|
}
|
|
23819
|
-
function envelope(
|
|
23820
|
-
return { id: randomUUID(), boardId:
|
|
23866
|
+
function envelope(boardId3, op, actorId) {
|
|
23867
|
+
return { id: randomUUID(), boardId: boardId3, clientId: CLIENT_ID, actorId, seq: null, ts: Date.now(), op };
|
|
23821
23868
|
}
|
|
23822
23869
|
function checkEnvelope(env) {
|
|
23823
23870
|
const bad = checkOp(env.op);
|
|
@@ -24067,6 +24114,289 @@ function touchedNodes(envelopes) {
|
|
|
24067
24114
|
return out;
|
|
24068
24115
|
}
|
|
24069
24116
|
|
|
24117
|
+
// src/canvas/comments.ts
|
|
24118
|
+
function mmss(t) {
|
|
24119
|
+
const total = Math.max(0, Math.floor(t));
|
|
24120
|
+
const h = Math.floor(total / 3600);
|
|
24121
|
+
const m = Math.floor(total % 3600 / 60);
|
|
24122
|
+
const s = total % 60;
|
|
24123
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
24124
|
+
return h ? `${h}:${pad(m)}:${pad(s)}` : `${pad(m)}:${pad(s)}`;
|
|
24125
|
+
}
|
|
24126
|
+
function nodeRef(doc, nodeId) {
|
|
24127
|
+
const node = doc.nodes[nodeId];
|
|
24128
|
+
const kind = nodeKind(node) ?? node.type;
|
|
24129
|
+
return `"${oneLine(nodeName(node), 60)}" (${kind}, ${node.id})`;
|
|
24130
|
+
}
|
|
24131
|
+
function hashString(text) {
|
|
24132
|
+
let h1 = 3735928559;
|
|
24133
|
+
let h2 = 1103547991;
|
|
24134
|
+
for (let i = 0; i < text.length; i += 1) {
|
|
24135
|
+
const ch = text.charCodeAt(i);
|
|
24136
|
+
h1 = Math.imul(h1 ^ ch, 2654435761);
|
|
24137
|
+
h2 = Math.imul(h2 ^ ch, 1597334677);
|
|
24138
|
+
}
|
|
24139
|
+
h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507) ^ Math.imul(h2 ^ h2 >>> 13, 3266489909);
|
|
24140
|
+
h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507) ^ Math.imul(h1 ^ h1 >>> 13, 3266489909);
|
|
24141
|
+
const hex = (n) => (n >>> 0).toString(16).padStart(8, "0");
|
|
24142
|
+
return hex(h2) + hex(h1);
|
|
24143
|
+
}
|
|
24144
|
+
function outputKeyOf(entry) {
|
|
24145
|
+
for (const field of [entry.resultId, entry.id, entry.generationId]) {
|
|
24146
|
+
if (typeof field === "string" && field !== "" && field.length <= 128) return field;
|
|
24147
|
+
}
|
|
24148
|
+
if (typeof entry.url === "string" && entry.url !== "") return `url-${hashString(entry.url)}`;
|
|
24149
|
+
return null;
|
|
24150
|
+
}
|
|
24151
|
+
function versionOf(doc, nodeId, outputKey) {
|
|
24152
|
+
const ids = doc.nodeHistory?.[nodeId];
|
|
24153
|
+
if (Array.isArray(ids)) {
|
|
24154
|
+
const i = ids.indexOf(outputKey);
|
|
24155
|
+
if (i >= 0) return i + 1;
|
|
24156
|
+
}
|
|
24157
|
+
const history = doc.nodes[nodeId]?.data.history;
|
|
24158
|
+
if (Array.isArray(history)) {
|
|
24159
|
+
const i = history.findIndex(
|
|
24160
|
+
(h) => typeof h === "object" && h !== null && !Array.isArray(h) && outputKeyOf(h) === outputKey
|
|
24161
|
+
);
|
|
24162
|
+
if (i >= 0) return history.length - i;
|
|
24163
|
+
}
|
|
24164
|
+
return null;
|
|
24165
|
+
}
|
|
24166
|
+
function describeAnchor(anchor, doc) {
|
|
24167
|
+
if (!anchor || anchor.kind === "point") return { text: "no board" };
|
|
24168
|
+
const exists = !!doc.nodes[anchor.nodeId];
|
|
24169
|
+
if (!exists) {
|
|
24170
|
+
return { text: `no n\xF3 ${anchor.nodeId}`, gone: "o n\xF3 foi apagado" };
|
|
24171
|
+
}
|
|
24172
|
+
const ref = nodeRef(doc, anchor.nodeId);
|
|
24173
|
+
switch (anchor.kind) {
|
|
24174
|
+
case "node":
|
|
24175
|
+
return { text: `no n\xF3 ${ref}`, nodeId: anchor.nodeId };
|
|
24176
|
+
case "output": {
|
|
24177
|
+
const v = versionOf(doc, anchor.nodeId, anchor.outputKey);
|
|
24178
|
+
return v === null ? { text: `numa vers\xE3o de ${ref} (${anchor.outputKey})`, nodeId: anchor.nodeId, gone: "essa vers\xE3o n\xE3o est\xE1 mais no hist\xF3rico do n\xF3" } : { text: `na vers\xE3o ${v} de ${ref}`, nodeId: anchor.nodeId };
|
|
24179
|
+
}
|
|
24180
|
+
case "timecode": {
|
|
24181
|
+
const node = doc.nodes[anchor.nodeId];
|
|
24182
|
+
const kind = nodeKind(node);
|
|
24183
|
+
const t = mmss(Number(anchor.t) || 0);
|
|
24184
|
+
if (kind === "montage") {
|
|
24185
|
+
const name = nodeName(node);
|
|
24186
|
+
const title = name === KINDS.montage.title ? "" : ` "${oneLine(name, 60)}"`;
|
|
24187
|
+
return { text: `em ${t} da Montagem${title} (${node.id})`, nodeId: anchor.nodeId };
|
|
24188
|
+
}
|
|
24189
|
+
return { text: `em ${t} de ${ref}`, nodeId: anchor.nodeId };
|
|
24190
|
+
}
|
|
24191
|
+
default:
|
|
24192
|
+
return { text: "no board" };
|
|
24193
|
+
}
|
|
24194
|
+
}
|
|
24195
|
+
function who(c) {
|
|
24196
|
+
return c.author?.name?.trim() || "algu\xE9m";
|
|
24197
|
+
}
|
|
24198
|
+
function reactionsText(r) {
|
|
24199
|
+
if (Array.isArray(r)) {
|
|
24200
|
+
const parts = r.map((x) => {
|
|
24201
|
+
const rec = x ?? {};
|
|
24202
|
+
const emoji2 = typeof rec.emoji === "string" ? rec.emoji : null;
|
|
24203
|
+
const n = typeof rec.count === "number" ? rec.count : Array.isArray(rec.userIds) ? rec.userIds.length : Array.isArray(rec.users) ? rec.users.length : 1;
|
|
24204
|
+
return emoji2 ? `${emoji2}${n > 1 ? `\xD7${n}` : ""}` : null;
|
|
24205
|
+
}).filter(Boolean);
|
|
24206
|
+
return parts.join(" ");
|
|
24207
|
+
}
|
|
24208
|
+
if (r && typeof r === "object") {
|
|
24209
|
+
return Object.entries(r).map(([emoji2, v]) => {
|
|
24210
|
+
const n = Array.isArray(v) ? v.length : typeof v === "number" ? v : 1;
|
|
24211
|
+
return `${emoji2}${n > 1 ? `\xD7${n}` : ""}`;
|
|
24212
|
+
}).join(" ");
|
|
24213
|
+
}
|
|
24214
|
+
return "";
|
|
24215
|
+
}
|
|
24216
|
+
var MAX_REPLIES = 5;
|
|
24217
|
+
function threadLines(t, doc) {
|
|
24218
|
+
const where = describeAnchor(t.anchor, doc);
|
|
24219
|
+
const state = t.resolvedAt ? " \xB7 RESOLVIDO" : "";
|
|
24220
|
+
const reacts = reactionsText(t.reactions);
|
|
24221
|
+
const lines = t.deleted ? [`- ${t.id} \xB7 ${where.text}${state}`, " (coment\xE1rio raiz apagado: n\xE3o d\xE1 para responder nem resolver)"] : [`- ${t.id} \xB7 ${where.text} \xB7 ${who(t)}${state}${reacts ? ` \xB7 ${reacts}` : ""}`, ` pedido: ${oneLine(t.body ?? "", 400)}`];
|
|
24222
|
+
if (where.gone && !t.deleted) lines.push(` \u26A0 ALVO SUMIU: ${where.gone}. Responda com pergunta, n\xE3o resolva.`);
|
|
24223
|
+
const replies = Array.isArray(t.replies) ? t.replies : [];
|
|
24224
|
+
for (const r of replies.slice(-MAX_REPLIES)) {
|
|
24225
|
+
lines.push(r.deleted ? " \u21B3 (resposta apagada)" : ` \u21B3 ${who(r)}: ${oneLine(r.body ?? "", 140)}`);
|
|
24226
|
+
}
|
|
24227
|
+
if (replies.length > MAX_REPLIES) lines.splice(lines.length - MAX_REPLIES, 0, ` \u21B3 \u2026 ${replies.length - MAX_REPLIES} resposta(s) antes`);
|
|
24228
|
+
return lines;
|
|
24229
|
+
}
|
|
24230
|
+
function commentsSummary(threads, doc, status) {
|
|
24231
|
+
const label = status === "resolved" ? "resolvido(s)" : status === "all" ? "no total" : "aberto(s)";
|
|
24232
|
+
if (!threads.length) return `Nenhum coment\xE1rio ${label === "no total" ? "no board" : label}.`;
|
|
24233
|
+
const out = [`${threads.length} coment\xE1rio(s) ${label}:`];
|
|
24234
|
+
for (const t of threads) out.push(...threadLines(t, doc));
|
|
24235
|
+
return out.join("\n");
|
|
24236
|
+
}
|
|
24237
|
+
|
|
24238
|
+
// src/tools/canvas-comments.ts
|
|
24239
|
+
var boardId = external_exports.string().uuid().describe("Id (uuid) do board.");
|
|
24240
|
+
var commentId = external_exports.string().min(1).max(128).describe("Id do coment\xE1rio raiz, como sai em canvas_list_comments.");
|
|
24241
|
+
var body = external_exports.string().trim().min(1).max(4e3);
|
|
24242
|
+
var mentions = external_exports.array(external_exports.string().uuid()).max(50).optional().describe("userIds a marcar (opcional; quem n\xE3o \xE9 membro \xE9 ignorado).");
|
|
24243
|
+
function registerCanvasCommentTools(server, api, run) {
|
|
24244
|
+
async function onComment(fn) {
|
|
24245
|
+
try {
|
|
24246
|
+
return await fn();
|
|
24247
|
+
} catch (e) {
|
|
24248
|
+
if (!(e instanceof ApiError)) throw e;
|
|
24249
|
+
if (e.httpStatus === 404) {
|
|
24250
|
+
throw new CanvasToolError("Coment\xE1rio (ou board) n\xE3o encontrado ou apagado. Liste de novo com canvas_list_comments.");
|
|
24251
|
+
}
|
|
24252
|
+
if (e.httpStatus === 400) throw new CanvasToolError(`O servidor recusou o coment\xE1rio: ${e.message}.`);
|
|
24253
|
+
if (e.httpStatus === 403 && (!api.usesPat || /ialab:/.test(e.message))) {
|
|
24254
|
+
throw new CanvasToolError(
|
|
24255
|
+
"O login pelo navegador deste MCP n\xE3o tem a permiss\xE3o ialab:spend, que toda escrita de coment\xE1rio exige. Rode `beplus-mcp login` de novo e autorize a permiss\xE3o de gastar/editar."
|
|
24256
|
+
);
|
|
24257
|
+
}
|
|
24258
|
+
if (e.httpStatus === 403) throw new CanvasToolError(`Sem permiss\xE3o: ${e.message}.`);
|
|
24259
|
+
if (e.httpStatus === 429) {
|
|
24260
|
+
throw new CanvasToolError(
|
|
24261
|
+
"Limite de escrita em coment\xE1rios (60 por minuto por pessoa) mesmo depois de esperar. Pare o lote, diga \xE0 pessoa quais j\xE1 foram fechados e siga daqui a 1 minuto a partir do pr\xF3ximo."
|
|
24262
|
+
);
|
|
24263
|
+
}
|
|
24264
|
+
throw e;
|
|
24265
|
+
}
|
|
24266
|
+
}
|
|
24267
|
+
const newReplyId = (thread) => {
|
|
24268
|
+
const last = thread?.replies?.at(-1);
|
|
24269
|
+
return last?.id ?? "?";
|
|
24270
|
+
};
|
|
24271
|
+
server.registerTool(
|
|
24272
|
+
"canvas_list_comments",
|
|
24273
|
+
{
|
|
24274
|
+
title: "Canvas: listar coment\xE1rios",
|
|
24275
|
+
description: "Lista os coment\xE1rios de um board (padr\xE3o: abertos): id, onde est\xE1 (n\xF3, vers\xE3o, minutagem da Montagem ou board), autor, pedido e respostas. Avisa quando o alvo sumiu. S\xF3 leitura.",
|
|
24276
|
+
inputSchema: {
|
|
24277
|
+
board_id: boardId,
|
|
24278
|
+
status: external_exports.enum(["open", "resolved", "all"]).optional().describe("open (padr\xE3o), resolved ou all.")
|
|
24279
|
+
},
|
|
24280
|
+
annotations: { readOnlyHint: true, openWorldHint: false }
|
|
24281
|
+
},
|
|
24282
|
+
async ({ board_id, status }) => run(async () => {
|
|
24283
|
+
const st = status ?? "open";
|
|
24284
|
+
const [snap, threads] = await Promise.all([api.snapshot(board_id), api.listComments(board_id, st)]);
|
|
24285
|
+
const text = commentsSummary(threads, snap.doc, st);
|
|
24286
|
+
const open2 = threads.some((t) => !t.resolvedAt);
|
|
24287
|
+
return open2 ? `${text}
|
|
24288
|
+
|
|
24289
|
+
Para aplicar: leia o n\xF3 com canvas_read_board (node_ids), edite pelas canvas_* e feche com canvas_resolve_comment dizendo o que fez.` : text;
|
|
24290
|
+
})
|
|
24291
|
+
);
|
|
24292
|
+
server.registerTool(
|
|
24293
|
+
"canvas_reply_comment",
|
|
24294
|
+
{
|
|
24295
|
+
title: "Canvas: responder coment\xE1rio",
|
|
24296
|
+
description: "Responde numa thread de coment\xE1rio sem resolver. Use para perguntar quando o pedido \xE9 amb\xEDguo ou o alvo sumiu.",
|
|
24297
|
+
inputSchema: { board_id: boardId, comment_id: commentId, body, mentions },
|
|
24298
|
+
annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false }
|
|
24299
|
+
},
|
|
24300
|
+
async ({ board_id, comment_id, body: text, mentions: m }) => run(async () => {
|
|
24301
|
+
const thread = await onComment(
|
|
24302
|
+
() => api.createComment(board_id, { body: text, parentId: comment_id, ...m?.length ? { mentions: m } : {} })
|
|
24303
|
+
);
|
|
24304
|
+
const open2 = thread?.resolvedAt ? "A thread est\xE1 resolvida; reabra com canvas_reopen_comment se precisar." : "A thread segue aberta.";
|
|
24305
|
+
return `\u2705 Resposta ${newReplyId(thread)} em ${comment_id}: "${oneLine(text, 120)}". ${open2}`;
|
|
24306
|
+
})
|
|
24307
|
+
);
|
|
24308
|
+
server.registerTool(
|
|
24309
|
+
"canvas_resolve_comment",
|
|
24310
|
+
{
|
|
24311
|
+
title: "Canvas: resolver coment\xE1rio",
|
|
24312
|
+
description: "Fecha um coment\xE1rio depois de aplicar o ajuste. done \xE9 obrigat\xF3rio: uma frase curta dizendo o que foi feito (vira resposta na thread antes de resolver). N\xE3o resolva pedido amb\xEDguo nem com alvo sumido: responda com pergunta.",
|
|
24313
|
+
inputSchema: {
|
|
24314
|
+
board_id: boardId,
|
|
24315
|
+
comment_id: commentId,
|
|
24316
|
+
done: external_exports.string().trim().min(3).max(500).describe('O que foi feito, ex.: "troquei a fala do b2 e encurtei o b3".')
|
|
24317
|
+
},
|
|
24318
|
+
annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false }
|
|
24319
|
+
},
|
|
24320
|
+
async ({ board_id, comment_id, done }) => run(async () => {
|
|
24321
|
+
const thread = await onComment(() => api.createComment(board_id, { body: done, parentId: comment_id }));
|
|
24322
|
+
const replyId = newReplyId(thread);
|
|
24323
|
+
try {
|
|
24324
|
+
await onComment(() => api.resolveComment(board_id, comment_id));
|
|
24325
|
+
} catch (e) {
|
|
24326
|
+
const why = e instanceof Error ? e.message : String(e);
|
|
24327
|
+
throw new CanvasToolError(
|
|
24328
|
+
`A resposta "${oneLine(done, 80)}" (${replyId}) foi postada em ${comment_id}, mas resolver falhou: ${why} N\xE3o repita canvas_resolve_comment (postaria a resposta de novo): avise a pessoa para resolver no Canvas.`
|
|
24329
|
+
);
|
|
24330
|
+
}
|
|
24331
|
+
return `\u2705 Resolvido ${comment_id}: "${oneLine(done, 120)}" (resposta ${replyId}).`;
|
|
24332
|
+
})
|
|
24333
|
+
);
|
|
24334
|
+
server.registerTool(
|
|
24335
|
+
"canvas_reopen_comment",
|
|
24336
|
+
{
|
|
24337
|
+
title: "Canvas: reabrir coment\xE1rio",
|
|
24338
|
+
description: "Reabre um coment\xE1rio resolvido. why (opcional) vira resposta na thread explicando o motivo.",
|
|
24339
|
+
inputSchema: { board_id: boardId, comment_id: commentId, why: external_exports.string().trim().min(1).max(1e3).optional() },
|
|
24340
|
+
annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false }
|
|
24341
|
+
},
|
|
24342
|
+
async ({ board_id, comment_id, why }) => run(async () => {
|
|
24343
|
+
await onComment(() => api.reopenComment(board_id, comment_id));
|
|
24344
|
+
if (why) await onComment(() => api.createComment(board_id, { body: why, parentId: comment_id }));
|
|
24345
|
+
return `\u2705 Reaberto ${comment_id}${why ? ` com a resposta "${oneLine(why, 120)}"` : ""}.`;
|
|
24346
|
+
})
|
|
24347
|
+
);
|
|
24348
|
+
server.registerTool(
|
|
24349
|
+
"canvas_comment",
|
|
24350
|
+
{
|
|
24351
|
+
title: "Canvas: comentar",
|
|
24352
|
+
description: "Cria um coment\xE1rio novo (raiz), ancorado para aparecer no lugar certo do Canvas. Use para deixar uma pergunta ou observa\xE7\xE3o para a pessoa. \xC2ncora: node_id (no n\xF3); node_id + output_key (numa vers\xE3o gerada); node_id + t em segundos (minutagem da Montagem ou do v\xEDdeo); x,y (ponto do board); nada = acima do conte\xFAdo do board.",
|
|
24353
|
+
inputSchema: {
|
|
24354
|
+
board_id: boardId,
|
|
24355
|
+
body,
|
|
24356
|
+
node_id: external_exports.string().min(1).max(64).optional(),
|
|
24357
|
+
output_key: external_exports.string().min(1).max(128).optional().describe("Id da vers\xE3o (resultado) do n\xF3."),
|
|
24358
|
+
t: external_exports.number().finite().min(0).optional().describe("Segundos desde o in\xEDcio."),
|
|
24359
|
+
x: external_exports.number().finite().optional(),
|
|
24360
|
+
y: external_exports.number().finite().optional(),
|
|
24361
|
+
mentions
|
|
24362
|
+
},
|
|
24363
|
+
annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false }
|
|
24364
|
+
},
|
|
24365
|
+
async (args) => run(async () => {
|
|
24366
|
+
if (!args.node_id && (args.output_key !== void 0 || args.t !== void 0)) {
|
|
24367
|
+
throw new CanvasToolError("output_key e t precisam de node_id.");
|
|
24368
|
+
}
|
|
24369
|
+
if (args.output_key !== void 0 && args.t !== void 0) throw new CanvasToolError("Use output_key ou t, n\xE3o os dois.");
|
|
24370
|
+
if (args.x === void 0 !== (args.y === void 0)) throw new CanvasToolError("Informe x e y juntos.");
|
|
24371
|
+
const snap = await api.snapshot(args.board_id);
|
|
24372
|
+
let anchor;
|
|
24373
|
+
if (args.node_id) {
|
|
24374
|
+
if (!snap.doc.nodes[args.node_id]) {
|
|
24375
|
+
throw new CanvasToolError(`N\xF3 ${args.node_id} n\xE3o existe no board. Releia com canvas_read_board.`);
|
|
24376
|
+
}
|
|
24377
|
+
if (args.output_key !== void 0) anchor = { kind: "output", nodeId: args.node_id, outputKey: args.output_key };
|
|
24378
|
+
else if (args.t !== void 0) anchor = { kind: "timecode", nodeId: args.node_id, t: args.t };
|
|
24379
|
+
else anchor = { kind: "node", nodeId: args.node_id, dx: 0, dy: 0 };
|
|
24380
|
+
} else if (args.x !== void 0 && args.y !== void 0) {
|
|
24381
|
+
anchor = { kind: "point", x: args.x, y: args.y };
|
|
24382
|
+
} else {
|
|
24383
|
+
const nodes = Object.values(snap.doc.nodes);
|
|
24384
|
+
anchor = nodes.length ? { kind: "point", x: Math.min(...nodes.map((n) => n.position.x)), y: Math.min(...nodes.map((n) => n.position.y)) - 80 } : { kind: "point", x: 0, y: 0 };
|
|
24385
|
+
}
|
|
24386
|
+
const created = await onComment(
|
|
24387
|
+
() => api.createComment(args.board_id, {
|
|
24388
|
+
body: args.body,
|
|
24389
|
+
anchor,
|
|
24390
|
+
...args.mentions?.length ? { mentions: args.mentions } : {}
|
|
24391
|
+
})
|
|
24392
|
+
);
|
|
24393
|
+
const where = describeAnchor(anchor, snap.doc).text;
|
|
24394
|
+
const at = anchor.kind === "point" && args.x !== void 0 ? ` em (${args.x}, ${args.y})` : "";
|
|
24395
|
+
return `\u2705 Coment\xE1rio ${created?.id ?? ""} criado ${where}${at}.`.replace(" ", " ");
|
|
24396
|
+
})
|
|
24397
|
+
);
|
|
24398
|
+
}
|
|
24399
|
+
|
|
24070
24400
|
// src/tools/canvas.ts
|
|
24071
24401
|
var REJECT_TEXT = {
|
|
24072
24402
|
"node-missing": "o n\xF3 n\xE3o existe mais (algu\xE9m apagou)",
|
|
@@ -24076,9 +24406,7 @@ var REJECT_TEXT = {
|
|
|
24076
24406
|
};
|
|
24077
24407
|
var SECTION_Z = -1e3;
|
|
24078
24408
|
var GAP = 80;
|
|
24079
|
-
var
|
|
24080
|
-
};
|
|
24081
|
-
var boardId = external_exports.string().uuid().describe("Id (uuid) do board, como sai em canvas_list_boards.");
|
|
24409
|
+
var boardId2 = external_exports.string().uuid().describe("Id (uuid) do board, como sai em canvas_list_boards.");
|
|
24082
24410
|
var nodeIdArg = external_exports.string().min(1).max(128);
|
|
24083
24411
|
var point = external_exports.object({ x: external_exports.number().finite(), y: external_exports.number().finite() });
|
|
24084
24412
|
function registerCanvasTools(server, client, cfg) {
|
|
@@ -24222,7 +24550,7 @@ Aviso: ${changesSince(theirs, doc)}.`;
|
|
|
24222
24550
|
title: "Canvas: ler board",
|
|
24223
24551
|
description: "L\xEA um board: n\xF3s (id, tipo, nome, campos principais), liga\xE7\xF5es e v\xEDnculo com o IA Lab, sem m\xEDdia. Obrigat\xF3rio antes de editar (vale para a sess\xE3o). node_ids devolve o data completo desses n\xF3s.",
|
|
24224
24552
|
inputSchema: {
|
|
24225
|
-
board_id:
|
|
24553
|
+
board_id: boardId2,
|
|
24226
24554
|
node_ids: external_exports.array(nodeIdArg).max(20).optional().describe("N\xF3s para ver o data inteiro (sem blobs).")
|
|
24227
24555
|
},
|
|
24228
24556
|
annotations: { readOnlyHint: true, openWorldHint: false }
|
|
@@ -24294,7 +24622,7 @@ N\xF3s: ${Object.entries(ids).map(([k, v]) => `${k}=${v}`).join(" \xB7 ")}` : ""
|
|
|
24294
24622
|
title: "Canvas: adicionar n\xF3",
|
|
24295
24623
|
description: `Adiciona um n\xF3 (n\xE3o executa). kind: ${kindList()}. data completa o padr\xE3o do tipo; label d\xE1 o nome. Sem position, nasce ao lado do n\xF3 ligado ou \xE0 direita do board. inputs/outputs j\xE1 ligam o n\xF3 no mesmo passo.`,
|
|
24296
24624
|
inputSchema: {
|
|
24297
|
-
board_id:
|
|
24625
|
+
board_id: boardId2,
|
|
24298
24626
|
kind: external_exports.string().min(1).max(40),
|
|
24299
24627
|
label: external_exports.string().trim().min(1).max(120).optional().describe("Nome do cart\xE3o (data.label)."),
|
|
24300
24628
|
data: external_exports.record(external_exports.unknown()).optional().describe("Campos do data. Ex.: narration {blocks:[{id,text}]}, text {text}, prompt {template}."),
|
|
@@ -24342,7 +24670,7 @@ N\xF3s: ${Object.entries(ids).map(([k, v]) => `${k}=${v}`).join(" \xB7 ")}` : ""
|
|
|
24342
24670
|
title: "Canvas: editar n\xF3",
|
|
24343
24671
|
description: "Muda campos do data de um n\xF3, chave a chave (null apaga a chave), sem executar. label renomeia. N\xE3o troca o tipo. Leia o n\xF3 com node_ids antes para n\xE3o sobrescrever o que outra pessoa escreveu.",
|
|
24344
24672
|
inputSchema: {
|
|
24345
|
-
board_id:
|
|
24673
|
+
board_id: boardId2,
|
|
24346
24674
|
node_id: nodeIdArg,
|
|
24347
24675
|
data: external_exports.record(external_exports.unknown()).optional().describe("Chaves de data a gravar. Valor null apaga a chave."),
|
|
24348
24676
|
label: external_exports.string().trim().min(1).max(120).optional(),
|
|
@@ -24379,7 +24707,7 @@ N\xF3s: ${Object.entries(ids).map(([k, v]) => `${k}=${v}`).join(" \xB7 ")}` : ""
|
|
|
24379
24707
|
title: "Canvas: ligar portas",
|
|
24380
24708
|
description: "Liga a sa\xEDda de um n\xF3 \xE0 entrada de outro (ids e portas de canvas_read_board). Liga\xE7\xE3o repetida \xE9 ignorada.",
|
|
24381
24709
|
inputSchema: {
|
|
24382
|
-
board_id:
|
|
24710
|
+
board_id: boardId2,
|
|
24383
24711
|
source: nodeIdArg,
|
|
24384
24712
|
source_port: external_exports.string().min(1).max(80),
|
|
24385
24713
|
target: nodeIdArg,
|
|
@@ -24406,7 +24734,7 @@ N\xF3s: ${Object.entries(ids).map(([k, v]) => `${k}=${v}`).join(" \xB7 ")}` : ""
|
|
|
24406
24734
|
title: "Canvas: apagar n\xF3s/liga\xE7\xF5es",
|
|
24407
24735
|
description: "Apaga n\xF3s (com as liga\xE7\xF5es e varia\xE7\xF5es deles) e/ou liga\xE7\xF5es, num passo s\xF3. Irrevers\xEDvel pelo MCP: confirme com o usu\xE1rio antes. N\xE3o apaga o board.",
|
|
24408
24736
|
inputSchema: {
|
|
24409
|
-
board_id:
|
|
24737
|
+
board_id: boardId2,
|
|
24410
24738
|
node_ids: external_exports.array(nodeIdArg).max(200).optional(),
|
|
24411
24739
|
edge_ids: external_exports.array(nodeIdArg).max(200).optional()
|
|
24412
24740
|
},
|
|
@@ -24450,7 +24778,7 @@ N\xF3s: ${Object.entries(ids).map(([k, v]) => `${k}=${v}`).join(" \xB7 ")}` : ""
|
|
|
24450
24778
|
{
|
|
24451
24779
|
title: "Canvas: renomear board",
|
|
24452
24780
|
description: "Troca o t\xEDtulo do board (board.set). Precisa de papel de editor ou dono.",
|
|
24453
|
-
inputSchema: { board_id:
|
|
24781
|
+
inputSchema: { board_id: boardId2, title: external_exports.string().trim().min(1).max(200) },
|
|
24454
24782
|
annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false }
|
|
24455
24783
|
},
|
|
24456
24784
|
async ({ board_id, title }) => run(
|
|
@@ -24466,7 +24794,7 @@ N\xF3s: ${Object.entries(ids).map(([k, v]) => `${k}=${v}`).join(" \xB7 ")}` : ""
|
|
|
24466
24794
|
{
|
|
24467
24795
|
title: "Canvas: membros do board",
|
|
24468
24796
|
description: "Lista quem tem acesso ao board (userId, nome, papel). S\xF3 leitura.",
|
|
24469
|
-
inputSchema: { board_id:
|
|
24797
|
+
inputSchema: { board_id: boardId2 },
|
|
24470
24798
|
annotations: { readOnlyHint: true, openWorldHint: false }
|
|
24471
24799
|
},
|
|
24472
24800
|
async ({ board_id }) => run(async () => {
|
|
@@ -24483,7 +24811,7 @@ N\xF3s: ${Object.entries(ids).map(([k, v]) => `${k}=${v}`).join(" \xB7 ")}` : ""
|
|
|
24483
24811
|
title: "Canvas: adicionar membro",
|
|
24484
24812
|
description: "D\xE1 acesso ao board (ou troca o papel) para um usu\xE1rio pelo userId (uuid). S\xF3 o dono pode. Ainda n\xE3o h\xE1 busca por e-mail: pe\xE7a o userId ou copie de canvas_list_members de outro board.",
|
|
24485
24813
|
inputSchema: {
|
|
24486
|
-
board_id:
|
|
24814
|
+
board_id: boardId2,
|
|
24487
24815
|
user_id: external_exports.string().uuid(),
|
|
24488
24816
|
role: external_exports.enum(["editor", "viewer"]).describe("editor edita; viewer s\xF3 v\xEA.")
|
|
24489
24817
|
},
|
|
@@ -24499,7 +24827,7 @@ N\xF3s: ${Object.entries(ids).map(([k, v]) => `${k}=${v}`).join(" \xB7 ")}` : ""
|
|
|
24499
24827
|
{
|
|
24500
24828
|
title: "Canvas: remover membro",
|
|
24501
24829
|
description: "Tira o acesso de algu\xE9m ao board (o dono tira qualquer um; quem n\xE3o \xE9 dono s\xF3 sai sozinho). O dono n\xE3o sai.",
|
|
24502
|
-
inputSchema: { board_id:
|
|
24830
|
+
inputSchema: { board_id: boardId2, user_id: external_exports.string().uuid() },
|
|
24503
24831
|
annotations: { readOnlyHint: false, destructiveHint: true, openWorldHint: false }
|
|
24504
24832
|
},
|
|
24505
24833
|
async ({ board_id, user_id }) => run(async () => {
|
|
@@ -24507,13 +24835,14 @@ N\xF3s: ${Object.entries(ids).map(([k, v]) => `${k}=${v}`).join(" \xB7 ")}` : ""
|
|
|
24507
24835
|
return `\u2705 ${user_id} n\xE3o tem mais acesso ao board.`;
|
|
24508
24836
|
})
|
|
24509
24837
|
);
|
|
24838
|
+
registerCanvasCommentTools(server, api, run);
|
|
24510
24839
|
}
|
|
24511
24840
|
|
|
24512
24841
|
// src/version.ts
|
|
24513
24842
|
import { createRequire } from "module";
|
|
24514
24843
|
var require2 = createRequire(import.meta.url);
|
|
24515
24844
|
function readVersion() {
|
|
24516
|
-
if ("0.
|
|
24845
|
+
if ("0.27.0") return "0.27.0";
|
|
24517
24846
|
try {
|
|
24518
24847
|
const pkg = require2("../package.json");
|
|
24519
24848
|
return pkg.version ?? "0.0.0-unknown";
|
|
@@ -24528,7 +24857,8 @@ var SERVER_INSTRUCTIONS = [
|
|
|
24528
24857
|
"BePlus: tudo roda pela conta do usu\xE1rio (diamantes, limites e hist\xF3rico na plataforma).",
|
|
24529
24858
|
'M\xEDdia: generate_* gasta diamantes; confira com estimate_cost antes de lotes grandes. Sem project, a gera\xE7\xE3o cai no projeto ativo; billing:"personal" cobra do usu\xE1rio.',
|
|
24530
24859
|
"Calls: search_calls acha, get_call traz a transcri\xE7\xE3o.",
|
|
24531
|
-
"Canvas online (canvas_*): leia com canvas_read_board antes de editar e siga o estado lido. Cada edi\xE7\xE3o vai num passo s\xF3; se outra pessoa mexeu nos mesmos n\xF3s, a ferramenta recusa e pede releitura. As ferramentas canvas_* n\xE3o geram m\xEDdia nem gastam diamantes: quem roda os n\xF3s \xE9 o usu\xE1rio no Canvas. D\xEA nome (label) aos n\xF3s, n\xE3o invente tipos nem portas, e confirme antes de canvas_delete."
|
|
24860
|
+
"Canvas online (canvas_*): leia com canvas_read_board antes de editar e siga o estado lido. Cada edi\xE7\xE3o vai num passo s\xF3; se outra pessoa mexeu nos mesmos n\xF3s, a ferramenta recusa e pede releitura. As ferramentas canvas_* n\xE3o geram m\xEDdia nem gastam diamantes: quem roda os n\xF3s \xE9 o usu\xE1rio no Canvas. D\xEA nome (label) aos n\xF3s, n\xE3o invente tipos nem portas, e confirme antes de canvas_delete.",
|
|
24861
|
+
'"Aplica os coment\xE1rios" do board: canvas_list_comments (abertos) \u2192 para cada um, leia o n\xF3 ancorado com canvas_read_board (node_ids), aplique a edi\xE7\xE3o pelas canvas_* e feche com canvas_resolve_comment dizendo em uma frase o que fez. Coment\xE1rio amb\xEDguo ou com alvo sumido: responda com pergunta (canvas_reply_comment) e n\xE3o resolva. D\xFAvida sua sobre um n\xF3: canvas_comment ancorado nele. As escritas j\xE1 saem espa\xE7adas (60/min); se ainda vier limite, pare e diga de onde seguir.'
|
|
24532
24862
|
].join("\n");
|
|
24533
24863
|
function buildServer(cfg) {
|
|
24534
24864
|
const server = new McpServer({ name: "beplus", version: VERSION }, { instructions: SERVER_INSTRUCTIONS });
|
|
@@ -24782,16 +25112,16 @@ async function json(url, init) {
|
|
|
24782
25112
|
throw new Error(`Nao consegui falar com ${new URL(url).origin}. Confira a rede e o BEPLUS_API_URL.`);
|
|
24783
25113
|
}
|
|
24784
25114
|
const text = await res.text();
|
|
24785
|
-
let
|
|
25115
|
+
let body2;
|
|
24786
25116
|
try {
|
|
24787
|
-
|
|
25117
|
+
body2 = text ? JSON.parse(text) : void 0;
|
|
24788
25118
|
} catch {
|
|
24789
25119
|
}
|
|
24790
25120
|
if (!res.ok) {
|
|
24791
|
-
const msg =
|
|
25121
|
+
const msg = body2?.message ?? body2?.error_description ?? body2?.error ?? `HTTP ${res.status}`;
|
|
24792
25122
|
throw new Error(`${msg} (${url})`);
|
|
24793
25123
|
}
|
|
24794
|
-
return
|
|
25124
|
+
return body2;
|
|
24795
25125
|
}
|
|
24796
25126
|
async function discover(apiUrl2) {
|
|
24797
25127
|
const meta = await json(`${apiUrl2}/.well-known/oauth-authorization-server`);
|