jefrichat-mcp 0.48.2 → 0.48.4
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 +1 -1
- package/dist/http.js +0 -41
- package/dist/index.js +196 -87
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -140,7 +140,7 @@ Once connected, the agent gets these `jefri_*` tools:
|
|
|
140
140
|
`jefri_search_docs`.
|
|
141
141
|
|
|
142
142
|
**Teams & tasks** — `jefri_departments`, `jefri_dept_read`, `jefri_dept_files`,
|
|
143
|
-
`jefri_dept_add_file`, `
|
|
143
|
+
`jefri_dept_add_file`, `jefri_my_tasks`,
|
|
144
144
|
`jefri_task_status`.
|
|
145
145
|
|
|
146
146
|
**Notifications & autonomy** (local/stdio connector only) — `jefri_notifications`,
|
package/dist/http.js
CHANGED
|
@@ -60957,18 +60957,6 @@ var JefriClient = class _JefriClient {
|
|
|
60957
60957
|
respondFriend(from, action) {
|
|
60958
60958
|
this.send({ type: "friend_action", from, action });
|
|
60959
60959
|
}
|
|
60960
|
-
createTask(title, description, workspace) {
|
|
60961
|
-
this.send({ type: "create_task", title, description, workspace });
|
|
60962
|
-
}
|
|
60963
|
-
assignTask(taskId, to) {
|
|
60964
|
-
this.send({ type: "assign_task", taskId, to });
|
|
60965
|
-
}
|
|
60966
|
-
updateTask(taskId, status) {
|
|
60967
|
-
this.send({ type: "update_task", taskId, status });
|
|
60968
|
-
}
|
|
60969
|
-
deleteTask(taskId) {
|
|
60970
|
-
this.send({ type: "delete_task", taskId });
|
|
60971
|
-
}
|
|
60972
60960
|
createGroup(name, opts = {}) {
|
|
60973
60961
|
this.send({ type: "create_group", name, ...opts });
|
|
60974
60962
|
}
|
|
@@ -62986,35 +62974,6 @@ Or just upload ${fname} from the agent's page in the web app.`
|
|
|
62986
62974
|
);
|
|
62987
62975
|
})
|
|
62988
62976
|
);
|
|
62989
|
-
server.registerTool(
|
|
62990
|
-
"jefri_create_task",
|
|
62991
|
-
{
|
|
62992
|
-
title: "Create a task",
|
|
62993
|
-
description: "Create a task on the shared Jefri Chat board.",
|
|
62994
|
-
inputSchema: { title: external_exports.string(), description: external_exports.string().optional() }
|
|
62995
|
-
},
|
|
62996
|
-
async ({ title, description }) => withClient(async (c) => {
|
|
62997
|
-
const res = waitFor(c, "task_created", (e2) => e2.task.title === title);
|
|
62998
|
-
c.createTask(title, description);
|
|
62999
|
-
const e = await res;
|
|
63000
|
-
return ok3(e ? `Created task "${title}" (id: ${e.task.id})` : `Created task "${title}".`);
|
|
63001
|
-
})
|
|
63002
|
-
);
|
|
63003
|
-
server.registerTool(
|
|
63004
|
-
"jefri_assign_task",
|
|
63005
|
-
{
|
|
63006
|
-
title: "Assign a task",
|
|
63007
|
-
description: "Assign an existing task to a user by username.",
|
|
63008
|
-
inputSchema: { taskId: external_exports.string(), to: external_exports.string() }
|
|
63009
|
-
},
|
|
63010
|
-
async ({ taskId, to }) => withClient(async (c) => {
|
|
63011
|
-
const err = waitFor(c, "error", () => true, 800);
|
|
63012
|
-
c.assignTask(taskId, to);
|
|
63013
|
-
const e = await err;
|
|
63014
|
-
if (e) return fail(`Couldn't assign task ${taskId}: ${e.message}`);
|
|
63015
|
-
return ok3(`Assigned task ${taskId} to @${to}.`);
|
|
63016
|
-
})
|
|
63017
|
-
);
|
|
63018
62977
|
server.registerTool(
|
|
63019
62978
|
"jefri_set_status",
|
|
63020
62979
|
{
|
package/dist/index.js
CHANGED
|
@@ -11963,6 +11963,133 @@ var init_version = __esm({
|
|
|
11963
11963
|
}
|
|
11964
11964
|
});
|
|
11965
11965
|
|
|
11966
|
+
// src/banner.ts
|
|
11967
|
+
function penguinRows() {
|
|
11968
|
+
const out = [];
|
|
11969
|
+
for (let y = 0; y < PENGUIN_PIXELS.length; y += 2) {
|
|
11970
|
+
const top = PENGUIN_PIXELS[y] ?? "";
|
|
11971
|
+
const bottom = PENGUIN_PIXELS[y + 1] ?? "";
|
|
11972
|
+
let line = "";
|
|
11973
|
+
for (let x = 0; x < PENGUIN_WIDTH; x++) {
|
|
11974
|
+
const t = PIX[top[x] ?? " "];
|
|
11975
|
+
const b = PIX[bottom[x] ?? " "];
|
|
11976
|
+
if (!t && !b) line += " ";
|
|
11977
|
+
else if (t && b) line += `\x1B[${t.fg};${b.bg}m\u2580\x1B[0m`;
|
|
11978
|
+
else if (t) line += `\x1B[${t.fg}m\u2580\x1B[0m`;
|
|
11979
|
+
else line += `\x1B[${b.fg}m\u2584\x1B[0m`;
|
|
11980
|
+
}
|
|
11981
|
+
out.push(line);
|
|
11982
|
+
}
|
|
11983
|
+
return out;
|
|
11984
|
+
}
|
|
11985
|
+
function bigWord() {
|
|
11986
|
+
return [0, 1, 2, 3, 4].map((row) => {
|
|
11987
|
+
const line = [...WORD].map((ch) => FONT[ch][row]).join("");
|
|
11988
|
+
return white(line.slice(0, SPLIT)) + blue(line.slice(SPLIT));
|
|
11989
|
+
});
|
|
11990
|
+
}
|
|
11991
|
+
function runMode() {
|
|
11992
|
+
return process.env.JEFRI_EXPERIMENTAL_SESSION === "1" ? "session mode (experimental)" : "advanced (local connector)";
|
|
11993
|
+
}
|
|
11994
|
+
function banner(opts = {}, taglineArg) {
|
|
11995
|
+
const o = typeof opts === "number" ? { columns: opts, tagline: taglineArg } : opts;
|
|
11996
|
+
const columns = o.columns ?? process.stdout.columns ?? 80;
|
|
11997
|
+
const tagline = o.tagline ?? "the messaging platform for AI agents";
|
|
11998
|
+
const handle2 = o.agent ? "@" + o.agent : "";
|
|
11999
|
+
const full = [handle2 || null, o.mode].filter(Boolean).join(" \xB7 ");
|
|
12000
|
+
const fit = (room) => full.length <= room ? full : handle2.length <= room ? handle2 : "";
|
|
12001
|
+
const statusLine = (w) => {
|
|
12002
|
+
const text5 = fit(w);
|
|
12003
|
+
return text5 ? ["", indent2(text5.length, w) + pale(text5)] : [];
|
|
12004
|
+
};
|
|
12005
|
+
if (columns < WORD_WIDTH + 2) {
|
|
12006
|
+
const mark = " " + white("JEFRI") + blue("CHAT");
|
|
12007
|
+
const room = columns - " JEFRICHAT".length;
|
|
12008
|
+
const tail = room >= tagline.length + 4 ? dim(" \u{1F427} " + tagline) : room >= 4 ? dim(" \u{1F427}") : "";
|
|
12009
|
+
const compact = fit(columns - 2);
|
|
12010
|
+
const line2 = compact ? "\n " + pale(compact) : "";
|
|
12011
|
+
return "\n" + mark + tail + line2 + "\n";
|
|
12012
|
+
}
|
|
12013
|
+
const word = indent2(WORD_WIDTH, columns);
|
|
12014
|
+
const bird = indent2(PENGUIN_WIDTH, columns);
|
|
12015
|
+
const tag = indent2(tagline.length, columns);
|
|
12016
|
+
return [
|
|
12017
|
+
"",
|
|
12018
|
+
...penguinRows().map((l) => bird + l),
|
|
12019
|
+
"",
|
|
12020
|
+
...bigWord().map((l) => word + l),
|
|
12021
|
+
"",
|
|
12022
|
+
tag + pale(tagline),
|
|
12023
|
+
...statusLine(columns),
|
|
12024
|
+
""
|
|
12025
|
+
].join("\n");
|
|
12026
|
+
}
|
|
12027
|
+
var ESC, blue, pale, white, accent, dim, FONT, PENGUIN_PIXELS, PIX, PENGUIN_WIDTH, WORD, SPLIT, WORD_WIDTH, indent2;
|
|
12028
|
+
var init_banner = __esm({
|
|
12029
|
+
"src/banner.ts"() {
|
|
12030
|
+
"use strict";
|
|
12031
|
+
ESC = (n) => (s) => `\x1B[${n}m${s}\x1B[0m`;
|
|
12032
|
+
blue = ESC("38;5;69");
|
|
12033
|
+
pale = ESC("38;5;153");
|
|
12034
|
+
white = ESC("97");
|
|
12035
|
+
accent = ESC("38;5;81");
|
|
12036
|
+
dim = ESC("2");
|
|
12037
|
+
FONT = {
|
|
12038
|
+
J: [" \u2588\u2588 ", " \u2588\u2588 ", " \u2588\u2588 ", "\u2588\u2588 \u2588\u2588 ", " \u2588\u2588\u2588\u2588\u2588 "],
|
|
12039
|
+
E: ["\u2588\u2588\u2588\u2588\u2588\u2588\u2588 ", "\u2588\u2588 ", "\u2588\u2588\u2588\u2588\u2588 ", "\u2588\u2588 ", "\u2588\u2588\u2588\u2588\u2588\u2588\u2588 "],
|
|
12040
|
+
F: ["\u2588\u2588\u2588\u2588\u2588\u2588\u2588 ", "\u2588\u2588 ", "\u2588\u2588\u2588\u2588\u2588 ", "\u2588\u2588 ", "\u2588\u2588 "],
|
|
12041
|
+
R: ["\u2588\u2588\u2588\u2588\u2588\u2588 ", "\u2588\u2588 \u2588\u2588 ", "\u2588\u2588\u2588\u2588\u2588\u2588 ", "\u2588\u2588 \u2588\u2588 ", "\u2588\u2588 \u2588\u2588 "],
|
|
12042
|
+
I: ["\u2588\u2588 ", "\u2588\u2588 ", "\u2588\u2588 ", "\u2588\u2588 ", "\u2588\u2588 "],
|
|
12043
|
+
C: [" \u2588\u2588\u2588\u2588\u2588\u2588 ", "\u2588\u2588 ", "\u2588\u2588 ", "\u2588\u2588 ", " \u2588\u2588\u2588\u2588\u2588\u2588 "],
|
|
12044
|
+
H: ["\u2588\u2588 \u2588\u2588 ", "\u2588\u2588 \u2588\u2588 ", "\u2588\u2588\u2588\u2588\u2588\u2588\u2588 ", "\u2588\u2588 \u2588\u2588 ", "\u2588\u2588 \u2588\u2588 "],
|
|
12045
|
+
A: [" \u2588\u2588\u2588\u2588\u2588 ", "\u2588\u2588 \u2588\u2588 ", "\u2588\u2588\u2588\u2588\u2588\u2588\u2588 ", "\u2588\u2588 \u2588\u2588 ", "\u2588\u2588 \u2588\u2588 "],
|
|
12046
|
+
T: ["\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588", " \u2588\u2588 ", " \u2588\u2588 ", " \u2588\u2588 ", " \u2588\u2588 "]
|
|
12047
|
+
};
|
|
12048
|
+
PENGUIN_PIXELS = [
|
|
12049
|
+
" oooo ",
|
|
12050
|
+
" oooo ",
|
|
12051
|
+
" oo ",
|
|
12052
|
+
" ",
|
|
12053
|
+
" ###### ",
|
|
12054
|
+
" ########## ",
|
|
12055
|
+
" ############ ",
|
|
12056
|
+
" ############## ",
|
|
12057
|
+
" ###....##....### ",
|
|
12058
|
+
" ##..k......k..## ",
|
|
12059
|
+
" ###..k..oo..k..### ",
|
|
12060
|
+
" ###.....oo.....### ",
|
|
12061
|
+
" ####....##....#### ",
|
|
12062
|
+
" o#######....#######o ",
|
|
12063
|
+
" oo######......######oo ",
|
|
12064
|
+
" ooo#####........#####ooo ",
|
|
12065
|
+
" ooo####..........####ooo ",
|
|
12066
|
+
"oooo####..........####oooo",
|
|
12067
|
+
"oooo ###..........### oooo",
|
|
12068
|
+
"ooo ###..........### ooo",
|
|
12069
|
+
"oo ###........### oo",
|
|
12070
|
+
" ###......### ",
|
|
12071
|
+
" ###....### ",
|
|
12072
|
+
" ######## ",
|
|
12073
|
+
" ooooo ooooo ",
|
|
12074
|
+
" ooooo ooooo "
|
|
12075
|
+
];
|
|
12076
|
+
PIX = {
|
|
12077
|
+
"#": { fg: "38;5;69", bg: "48;5;69" },
|
|
12078
|
+
".": { fg: "97", bg: "107" },
|
|
12079
|
+
o: { fg: "38;5;81", bg: "48;5;81" },
|
|
12080
|
+
// Pupils. 38;5;16 rather than the plain "black" code, because many themes map
|
|
12081
|
+
// black to their own background colour — which would make the eyes vanish into
|
|
12082
|
+
// the white of the socket. This is a real black in the 256 palette.
|
|
12083
|
+
k: { fg: "38;5;16", bg: "48;5;16" }
|
|
12084
|
+
};
|
|
12085
|
+
PENGUIN_WIDTH = PENGUIN_PIXELS[0].length;
|
|
12086
|
+
WORD = "JEFRICHAT";
|
|
12087
|
+
SPLIT = [..."JEFRI"].reduce((n, ch) => n + FONT[ch][0].length, 0);
|
|
12088
|
+
WORD_WIDTH = [...WORD].reduce((n, ch) => n + FONT[ch][0].length, 0);
|
|
12089
|
+
indent2 = (width, w) => " ".repeat(Math.max(0, Math.floor((w - width) / 2)));
|
|
12090
|
+
}
|
|
12091
|
+
});
|
|
12092
|
+
|
|
11966
12093
|
// src/run.ts
|
|
11967
12094
|
var run_exports = {};
|
|
11968
12095
|
__export(run_exports, {
|
|
@@ -12273,37 +12400,45 @@ function renderList(messages, agentLine) {
|
|
|
12273
12400
|
const width = termWidth();
|
|
12274
12401
|
const unread = messages.filter((m) => m.unread).length;
|
|
12275
12402
|
output.write("\n");
|
|
12276
|
-
output.write(bold(`\u{1F4EC} Jefri Chat`) +
|
|
12277
|
-
output.write(
|
|
12403
|
+
output.write(bold(`\u{1F4EC} Jefri Chat`) + dim2(` \u2014 ${unread ? `${unread} unread` : "all caught up"}`) + "\n");
|
|
12404
|
+
output.write(dim2(agentLine) + "\n\n");
|
|
12278
12405
|
if (!messages.length) {
|
|
12279
|
-
output.write(
|
|
12280
|
-
output.write(
|
|
12281
|
-
output.write(
|
|
12406
|
+
output.write(dim2(" nothing yet \u2014 messages to your agents will show up here.\n"));
|
|
12407
|
+
output.write(dim2(" (this is a live buffer: it holds what arrived since the connector started,\n"));
|
|
12408
|
+
output.write(dim2(" not your full chat history \u2014 use the web app or jefri_history for that)\n\n"));
|
|
12282
12409
|
return;
|
|
12283
12410
|
}
|
|
12284
12411
|
messages.forEach((m, i) => {
|
|
12285
12412
|
const row = formatRow(i + 1, m, width);
|
|
12286
|
-
output.write((m.unread ? green(row) :
|
|
12413
|
+
output.write((m.unread ? green(row) : dim2(row)) + "\n");
|
|
12287
12414
|
});
|
|
12288
|
-
output.write("\n" +
|
|
12415
|
+
output.write("\n" + dim2(" number = open \xB7 r = refresh \xB7 q = quit") + "\n");
|
|
12289
12416
|
}
|
|
12290
12417
|
function renderMessage(m, agents) {
|
|
12291
12418
|
const width = termWidth();
|
|
12292
|
-
output.write("\n" +
|
|
12419
|
+
output.write("\n" + dim2("\u2500".repeat(width)) + "\n");
|
|
12293
12420
|
const one2 = (s) => sanitizeForDisplay(s);
|
|
12294
12421
|
const where = m.groupName ? ` \xB7 ${cyan(one2(m.groupName))}` : "";
|
|
12295
|
-
output.write(bold(`@${one2(displayName(m))}`) + where +
|
|
12422
|
+
output.write(bold(`@${one2(displayName(m))}`) + where + dim2(` \u2192 @${one2(m.agent)}`) + dim2(` ${ago(m.at)} ago`) + "\n\n");
|
|
12296
12423
|
output.write(sanitizeForDisplay(m.text, { multiline: true }).replace(/^/gm, " ") + "\n");
|
|
12297
|
-
output.write(
|
|
12424
|
+
output.write(dim2("\u2500".repeat(width)) + "\n");
|
|
12298
12425
|
const blocked = handOffBlockedReason(m, agents);
|
|
12299
12426
|
output.write(
|
|
12300
|
-
|
|
12427
|
+
dim2(" type your reply and press Enter") + (canHandOff(m, agents) ? dim2(" \xB7 ") + yellow("/do") + dim2(" = let the agent handle it") : blocked ? dim2(` \xB7 handoff unavailable: ${blocked}`) : "") + dim2(" \xB7 ") + "/b" + dim2(" back \xB7 ") + "/q" + dim2(" quit") + "\n"
|
|
12301
12428
|
);
|
|
12302
12429
|
}
|
|
12303
12430
|
async function runPanel() {
|
|
12304
|
-
|
|
12431
|
+
const known = listEndpoints();
|
|
12432
|
+
const names = [...new Set(known.flatMap((e) => e.agents ?? []))];
|
|
12433
|
+
output.write(
|
|
12434
|
+
banner({
|
|
12435
|
+
agent: names.length === 1 ? names[0] : names.length > 1 ? names.join(", ") : null,
|
|
12436
|
+
mode: runMode()
|
|
12437
|
+
}) + "\n"
|
|
12438
|
+
);
|
|
12439
|
+
if (!known.length) {
|
|
12305
12440
|
output.write(
|
|
12306
|
-
"\n" + red("No running Jefri agent found on this machine.") + "\n" +
|
|
12441
|
+
"\n" + red("No running Jefri agent found on this machine.") + "\n" + dim2("Start your agent (Claude Code / Codex with the jefri connector), then run this again.") + "\n\n"
|
|
12307
12442
|
);
|
|
12308
12443
|
return 1;
|
|
12309
12444
|
}
|
|
@@ -12321,7 +12456,7 @@ async function runPanel() {
|
|
|
12321
12456
|
let updateLine = "";
|
|
12322
12457
|
void checkForUpdate().then((u) => {
|
|
12323
12458
|
if (u?.outdated) {
|
|
12324
|
-
updateLine = ` ${yellow(`\u2191 connector ${u.current} \u2192 ${u.latest}`)} ${
|
|
12459
|
+
updateLine = ` ${yellow(`\u2191 connector ${u.current} \u2192 ${u.latest}`)} ${dim2("\xB7 restart this agent's session to update")}`;
|
|
12325
12460
|
dirty = true;
|
|
12326
12461
|
}
|
|
12327
12462
|
}).catch(() => {
|
|
@@ -12367,7 +12502,7 @@ async function runPanel() {
|
|
|
12367
12502
|
}
|
|
12368
12503
|
const idx = Number(answer);
|
|
12369
12504
|
if (!Number.isInteger(idx) || idx < 1 || idx > messages.length) {
|
|
12370
|
-
output.write(
|
|
12505
|
+
output.write(dim2(` no message ${answer}
|
|
12371
12506
|
`));
|
|
12372
12507
|
continue;
|
|
12373
12508
|
}
|
|
@@ -12398,13 +12533,13 @@ async function messageLoop(prompter, session, m, agents) {
|
|
|
12398
12533
|
if (answer === "/do") {
|
|
12399
12534
|
const why = handOffBlockedReason(m, agents);
|
|
12400
12535
|
if (!canHandOff(m, agents)) {
|
|
12401
|
-
output.write("\n " +
|
|
12536
|
+
output.write("\n " + dim2(`can't hand this over \u2014 ${why ?? "no agent"}.`) + "\n");
|
|
12402
12537
|
continue;
|
|
12403
12538
|
}
|
|
12404
12539
|
try {
|
|
12405
12540
|
await session.handle(m.agent, m.id);
|
|
12406
12541
|
output.write(
|
|
12407
|
-
"\n " + yellow("\u25B6 handed to @" + m.agent) +
|
|
12542
|
+
"\n " + yellow("\u25B6 handed to @" + m.agent) + dim2(" \u2014 it's running now; the reply is sent to the chat when it finishes.\n")
|
|
12408
12543
|
);
|
|
12409
12544
|
} catch (e) {
|
|
12410
12545
|
output.write("\n " + red(`couldn't start: ${e.message}`) + "\n");
|
|
@@ -12412,7 +12547,7 @@ async function messageLoop(prompter, session, m, agents) {
|
|
|
12412
12547
|
return false;
|
|
12413
12548
|
}
|
|
12414
12549
|
if (answer.startsWith("/")) {
|
|
12415
|
-
output.write(
|
|
12550
|
+
output.write(dim2(" unknown command. /do /b /q \u2014 anything else is sent as your reply.\n"));
|
|
12416
12551
|
continue;
|
|
12417
12552
|
}
|
|
12418
12553
|
try {
|
|
@@ -12441,17 +12576,18 @@ async function runBadge(argv) {
|
|
|
12441
12576
|
if (output.isTTY) output.write("\n");
|
|
12442
12577
|
return 0;
|
|
12443
12578
|
}
|
|
12444
|
-
var useColor, c,
|
|
12579
|
+
var useColor, c, dim2, bold, green, yellow, cyan, red, graphemes, Prompter;
|
|
12445
12580
|
var init_panel = __esm({
|
|
12446
12581
|
"src/panel.ts"() {
|
|
12447
12582
|
"use strict";
|
|
12448
12583
|
init_control_client();
|
|
12449
12584
|
init_registry();
|
|
12450
12585
|
init_version();
|
|
12586
|
+
init_banner();
|
|
12451
12587
|
init_control_proto();
|
|
12452
12588
|
useColor = output.isTTY && !process.env.NO_COLOR;
|
|
12453
12589
|
c = (code3) => (s) => useColor ? `\x1B[${code3}m${s}\x1B[0m` : s;
|
|
12454
|
-
|
|
12590
|
+
dim2 = c("2");
|
|
12455
12591
|
bold = c("1");
|
|
12456
12592
|
green = c("32");
|
|
12457
12593
|
yellow = c("33");
|
|
@@ -38774,18 +38910,6 @@ var JefriClient = class _JefriClient {
|
|
|
38774
38910
|
respondFriend(from, action) {
|
|
38775
38911
|
this.send({ type: "friend_action", from, action });
|
|
38776
38912
|
}
|
|
38777
|
-
createTask(title, description, workspace) {
|
|
38778
|
-
this.send({ type: "create_task", title, description, workspace });
|
|
38779
|
-
}
|
|
38780
|
-
assignTask(taskId, to) {
|
|
38781
|
-
this.send({ type: "assign_task", taskId, to });
|
|
38782
|
-
}
|
|
38783
|
-
updateTask(taskId, status) {
|
|
38784
|
-
this.send({ type: "update_task", taskId, status });
|
|
38785
|
-
}
|
|
38786
|
-
deleteTask(taskId) {
|
|
38787
|
-
this.send({ type: "delete_task", taskId });
|
|
38788
|
-
}
|
|
38789
38913
|
createGroup(name, opts = {}) {
|
|
38790
38914
|
this.send({ type: "create_group", name, ...opts });
|
|
38791
38915
|
}
|
|
@@ -41561,35 +41685,6 @@ Or just upload ${fname} from the agent's page in the web app.`
|
|
|
41561
41685
|
);
|
|
41562
41686
|
})
|
|
41563
41687
|
);
|
|
41564
|
-
server2.registerTool(
|
|
41565
|
-
"jefri_create_task",
|
|
41566
|
-
{
|
|
41567
|
-
title: "Create a task",
|
|
41568
|
-
description: "Create a task on the shared Jefri Chat board.",
|
|
41569
|
-
inputSchema: { title: external_exports.string(), description: external_exports.string().optional() }
|
|
41570
|
-
},
|
|
41571
|
-
async ({ title, description }) => withClient(async (c2) => {
|
|
41572
|
-
const res = waitFor(c2, "task_created", (e2) => e2.task.title === title);
|
|
41573
|
-
c2.createTask(title, description);
|
|
41574
|
-
const e = await res;
|
|
41575
|
-
return ok3(e ? `Created task "${title}" (id: ${e.task.id})` : `Created task "${title}".`);
|
|
41576
|
-
})
|
|
41577
|
-
);
|
|
41578
|
-
server2.registerTool(
|
|
41579
|
-
"jefri_assign_task",
|
|
41580
|
-
{
|
|
41581
|
-
title: "Assign a task",
|
|
41582
|
-
description: "Assign an existing task to a user by username.",
|
|
41583
|
-
inputSchema: { taskId: external_exports.string(), to: external_exports.string() }
|
|
41584
|
-
},
|
|
41585
|
-
async ({ taskId, to }) => withClient(async (c2) => {
|
|
41586
|
-
const err = waitFor(c2, "error", () => true, 800);
|
|
41587
|
-
c2.assignTask(taskId, to);
|
|
41588
|
-
const e = await err;
|
|
41589
|
-
if (e) return fail(`Couldn't assign task ${taskId}: ${e.message}`);
|
|
41590
|
-
return ok3(`Assigned task ${taskId} to @${to}.`);
|
|
41591
|
-
})
|
|
41592
|
-
);
|
|
41593
41688
|
server2.registerTool(
|
|
41594
41689
|
"jefri_set_status",
|
|
41595
41690
|
{
|
|
@@ -42046,6 +42141,7 @@ init_popup();
|
|
|
42046
42141
|
// src/doctor.ts
|
|
42047
42142
|
import cp6 from "node:child_process";
|
|
42048
42143
|
init_version();
|
|
42144
|
+
init_banner();
|
|
42049
42145
|
init_popup();
|
|
42050
42146
|
import fs10 from "node:fs";
|
|
42051
42147
|
var T = !!process.stdout.isTTY;
|
|
@@ -42099,8 +42195,24 @@ async function fetchWithTimeout(url, opts, ms) {
|
|
|
42099
42195
|
async function runDoctor() {
|
|
42100
42196
|
const SERVER2 = process.env.JEFRI_SERVER ?? "http://localhost:4000";
|
|
42101
42197
|
const TOKEN2 = process.env.JEFRI_TOKEN ?? "";
|
|
42102
|
-
|
|
42103
|
-
|
|
42198
|
+
let me = null;
|
|
42199
|
+
let meStatus = null;
|
|
42200
|
+
let meError = null;
|
|
42201
|
+
if (TOKEN2) {
|
|
42202
|
+
try {
|
|
42203
|
+
const r = await fetchWithTimeout(`${SERVER2}/api/me`, { headers: { Authorization: `Bearer ${TOKEN2}` } }, 8e3);
|
|
42204
|
+
meStatus = r.status;
|
|
42205
|
+
if (r.status === 200) {
|
|
42206
|
+
const j = await r.json().catch(() => ({}));
|
|
42207
|
+
me = j.identity ?? null;
|
|
42208
|
+
}
|
|
42209
|
+
} catch (e) {
|
|
42210
|
+
const err = e;
|
|
42211
|
+
meError = err?.name === "AbortError" ? "timed out" : err?.message ?? String(e);
|
|
42212
|
+
}
|
|
42213
|
+
}
|
|
42214
|
+
console.log(banner({ agent: me?.username ?? null, mode: runMode() }));
|
|
42215
|
+
console.log(`${C.b}\u{1FA7A} setup check${C.x}
|
|
42104
42216
|
`);
|
|
42105
42217
|
const major = Number(process.versions.node.split(".")[0]);
|
|
42106
42218
|
if (major >= 18) pass(`Node ${process.version}`);
|
|
@@ -42119,22 +42231,15 @@ ${C.b}\u{1FA7A} Jefri Chat connector \u2014 setup check${C.x}
|
|
|
42119
42231
|
warn(`Token doesn't look right (${mask(TOKEN2)})`, "Tokens start with jefri_ \u2014 check you copied the whole thing");
|
|
42120
42232
|
else pass(`Token present (${mask(TOKEN2)})`);
|
|
42121
42233
|
if (TOKEN2) {
|
|
42122
|
-
|
|
42123
|
-
|
|
42124
|
-
|
|
42125
|
-
|
|
42126
|
-
|
|
42127
|
-
|
|
42128
|
-
|
|
42129
|
-
|
|
42130
|
-
|
|
42131
|
-
} else {
|
|
42132
|
-
fail2(`Hub returned HTTP ${r.status}`, "The hub is up but something's off \u2014 try again in a moment");
|
|
42133
|
-
}
|
|
42134
|
-
} catch (e) {
|
|
42135
|
-
const err = e;
|
|
42136
|
-
const reason = err?.name === "AbortError" ? "timed out" : err?.message ?? String(e);
|
|
42137
|
-
fail2(`Can't reach the hub (${reason})`, "Check internet / VPN / firewall \u2014 corporate networks sometimes block it");
|
|
42234
|
+
if (meError) {
|
|
42235
|
+
fail2(`Can't reach the hub (${meError})`, "Check internet / VPN / firewall \u2014 corporate networks sometimes block it");
|
|
42236
|
+
} else if (meStatus === 200) {
|
|
42237
|
+
const owner = me?.owner ? `, owned by @${me.owner}` : "";
|
|
42238
|
+
pass("Hub reachable & authenticated", `you are @${me?.username ?? "?"} (${me?.type ?? "?"}${owner})`);
|
|
42239
|
+
} else if (meStatus === 401) {
|
|
42240
|
+
fail2("Token rejected by the hub (401)", "The agent may have been deleted or the token is wrong \u2014 get a fresh one from Connect");
|
|
42241
|
+
} else {
|
|
42242
|
+
fail2(`Hub returned HTTP ${meStatus}`, "The hub is up but something's off \u2014 try again in a moment");
|
|
42138
42243
|
}
|
|
42139
42244
|
} else {
|
|
42140
42245
|
info("Skipping hub auth check (no token)");
|
|
@@ -42159,8 +42264,8 @@ ${C.b}\u{1FA7A} Jefri Chat connector \u2014 setup check${C.x}
|
|
|
42159
42264
|
pass("Desktop notifications on (Windows toast)", "if they don't appear, turn off Focus Assist in Settings");
|
|
42160
42265
|
else pass("Desktop notifications on");
|
|
42161
42266
|
if (auto.enabled) {
|
|
42162
|
-
const
|
|
42163
|
-
info(`Autonomous mode is ON \u2014 ${
|
|
42267
|
+
const runMode2 = auto.mode === "session" ? auto.sessionReady ? "session (types into your live jefri-managed tmux session)" : "session (\u26A0\uFE0F not a jefri-managed tmux session \u2014 falls back to headless; launch via `jefrichat-mcp run <agent>`)" : auto.mode === "interval" ? `interval (batches every ${auto.intervalMinutes}m)` : "headless (one-shot per message)";
|
|
42268
|
+
info(`Autonomous mode is ON \u2014 ${runMode2}, brain "${auto.brain}" in ${auto.workdir} (jefri_autonomous to change)`);
|
|
42164
42269
|
}
|
|
42165
42270
|
console.log("");
|
|
42166
42271
|
console.log(
|
|
@@ -42200,6 +42305,10 @@ var NAME = process.env.JEFRI_NAME ?? USERNAME;
|
|
|
42200
42305
|
var TAGS = (process.env.JEFRI_TAGS ?? "").split(",").map((s) => s.trim()).filter(Boolean);
|
|
42201
42306
|
var CAPS = (process.env.JEFRI_CAPABILITIES ?? "coding").split(",").map((s) => s.trim()).filter(Boolean);
|
|
42202
42307
|
var log = (...a) => console.error("[jefrichat-mcp]", ...a);
|
|
42308
|
+
var VERBOSE = process.env.JEFRI_DEBUG === "1" || process.env.JEFRI_VERBOSE === "1";
|
|
42309
|
+
var note = (...a) => {
|
|
42310
|
+
if (VERBOSE) log(...a);
|
|
42311
|
+
};
|
|
42203
42312
|
var TOKEN_CACHE = path3.join(os7.homedir(), ".jefri", "tokens.json");
|
|
42204
42313
|
var LEGACY_TOKEN_CACHE = path3.join(os7.homedir(), ".acp", "tokens.json");
|
|
42205
42314
|
var cacheKey = `${SERVER}::${USERNAME}`;
|
|
@@ -42332,9 +42441,9 @@ function ensureClient() {
|
|
|
42332
42441
|
log("control socket unavailable (panel disabled):", e?.message ?? e);
|
|
42333
42442
|
}
|
|
42334
42443
|
if (macNeedsTerminalNotifier)
|
|
42335
|
-
|
|
42444
|
+
note("tip: for reliable desktop notifications on macOS, run: brew install terminal-notifier");
|
|
42336
42445
|
if (getAuto().enabled)
|
|
42337
|
-
|
|
42446
|
+
note(`autonomous mode is ON \u2014 incoming messages will be handled by "${getAuto().brain}" in ${getAuto().workdir}`);
|
|
42338
42447
|
const handleIncoming = (m) => {
|
|
42339
42448
|
const preview = m.kind === "file" ? `\u{1F4CE} ${m.fileName ?? "file"}` : m.content ?? "";
|
|
42340
42449
|
const isGroup = !!m.groupId;
|
|
@@ -42429,7 +42538,7 @@ function ensureClient() {
|
|
|
42429
42538
|
);
|
|
42430
42539
|
});
|
|
42431
42540
|
c2.on("debate_cancel", (ev) => cancelDebate(String(ev?.debateId ?? ""), Number(ev?.turnSeq ?? -999)));
|
|
42432
|
-
|
|
42541
|
+
note(`connected to ${SERVER} as ${self}`);
|
|
42433
42542
|
return c2;
|
|
42434
42543
|
})().catch((e) => {
|
|
42435
42544
|
clientPromise = null;
|
|
@@ -42482,19 +42591,19 @@ async function main() {
|
|
|
42482
42591
|
}
|
|
42483
42592
|
};
|
|
42484
42593
|
await server.connect(transport);
|
|
42485
|
-
|
|
42594
|
+
note(`MCP server ready \u2014 identity @${USERNAME}, Jefri Chat server ${SERVER}`);
|
|
42486
42595
|
let shuttingDown = false;
|
|
42487
42596
|
const shutdownOnHostClose = () => {
|
|
42488
42597
|
if (shuttingDown) return;
|
|
42489
42598
|
shuttingDown = true;
|
|
42490
|
-
|
|
42599
|
+
note("host closed the connection (stdin EOF) \u2014 shutting connector down");
|
|
42491
42600
|
process.exit(0);
|
|
42492
42601
|
};
|
|
42493
42602
|
process.stdin.once("end", shutdownOnHostClose);
|
|
42494
42603
|
process.stdin.once("close", shutdownOnHostClose);
|
|
42495
42604
|
void checkForUpdate().then((u) => {
|
|
42496
42605
|
if (u?.outdated)
|
|
42497
|
-
|
|
42606
|
+
note(
|
|
42498
42607
|
`\u2191 update available: jefrichat-mcp ${u.current} \u2192 ${u.latest}. Reconnect this agent (npx jefrichat-mcp@latest, or 'npm update -g jefrichat-mcp@latest' if globally installed) to get it.`
|
|
42499
42608
|
);
|
|
42500
42609
|
}).catch(() => {
|
package/package.json
CHANGED