nexrall-code 0.5.175 → 0.5.177
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/index.js +624 -60
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -110527,6 +110527,7 @@ var require_client2 = __commonJS({
|
|
|
110527
110527
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
110528
110528
|
exports2.McpClient = void 0;
|
|
110529
110529
|
exports2.flattenResourceContents = flattenResourceContents;
|
|
110530
|
+
exports2.flattenPromptMessages = flattenPromptMessages;
|
|
110530
110531
|
var child_process_1 = __require("child_process");
|
|
110531
110532
|
function flattenResourceContents(result, maxChars = 1e5) {
|
|
110532
110533
|
const contents = result?.contents ?? [];
|
|
@@ -110539,6 +110540,31 @@ var require_client2 = __commonJS({
|
|
|
110539
110540
|
}).filter(Boolean);
|
|
110540
110541
|
const text = parts.join("\n");
|
|
110541
110542
|
return text.length > maxChars ? text.slice(0, maxChars) + `
|
|
110543
|
+
\u2026 [truncated, ${text.length - maxChars} more characters]` : text;
|
|
110544
|
+
}
|
|
110545
|
+
function flattenPromptMessages(result, maxChars = 1e5) {
|
|
110546
|
+
const messages = result?.messages ?? [];
|
|
110547
|
+
const parts = messages.map((m2) => {
|
|
110548
|
+
const content = m2?.content;
|
|
110549
|
+
const items = Array.isArray(content) ? content : content ? [content] : [];
|
|
110550
|
+
return items.map((c) => {
|
|
110551
|
+
const item = c;
|
|
110552
|
+
if (item?.type === "text" && typeof item.text === "string")
|
|
110553
|
+
return item.text;
|
|
110554
|
+
if (item?.type === "image")
|
|
110555
|
+
return `[image prompt content (${item.mimeType ?? "unknown type"}) not shown]`;
|
|
110556
|
+
if (item?.type === "audio")
|
|
110557
|
+
return `[audio prompt content (${item.mimeType ?? "unknown type"}) not shown]`;
|
|
110558
|
+
if (item?.type === "resource") {
|
|
110559
|
+
if (typeof item.resource?.text === "string")
|
|
110560
|
+
return item.resource.text;
|
|
110561
|
+
return `[resource prompt content (${item.resource?.uri ?? "unknown uri"}) not shown]`;
|
|
110562
|
+
}
|
|
110563
|
+
return "";
|
|
110564
|
+
}).filter(Boolean).join("\n");
|
|
110565
|
+
}).filter(Boolean);
|
|
110566
|
+
const text = parts.join("\n\n");
|
|
110567
|
+
return text.length > maxChars ? text.slice(0, maxChars) + `
|
|
110542
110568
|
\u2026 [truncated, ${text.length - maxChars} more characters]` : text;
|
|
110543
110569
|
}
|
|
110544
110570
|
var McpClient = class {
|
|
@@ -110599,6 +110625,20 @@ var require_client2 = __commonJS({
|
|
|
110599
110625
|
async readResource(uri) {
|
|
110600
110626
|
return flattenResourceContents(await this._request("resources/read", { uri }));
|
|
110601
110627
|
}
|
|
110628
|
+
async listPrompts() {
|
|
110629
|
+
try {
|
|
110630
|
+
const res = await this._request("prompts/list", {});
|
|
110631
|
+
return Array.isArray(res?.prompts) ? res.prompts : [];
|
|
110632
|
+
} catch {
|
|
110633
|
+
return [];
|
|
110634
|
+
}
|
|
110635
|
+
}
|
|
110636
|
+
async getPrompt(name, args) {
|
|
110637
|
+
const params = { name };
|
|
110638
|
+
if (Object.keys(args).length)
|
|
110639
|
+
params.arguments = args;
|
|
110640
|
+
return flattenPromptMessages(await this._request("prompts/get", params));
|
|
110641
|
+
}
|
|
110602
110642
|
async callTool(name, args) {
|
|
110603
110643
|
const result = await this._request("tools/call", { name, arguments: args });
|
|
110604
110644
|
if (!result)
|
|
@@ -110726,6 +110766,20 @@ var require_httpClient = __commonJS({
|
|
|
110726
110766
|
async readResource(uri) {
|
|
110727
110767
|
return (0, client_1.flattenResourceContents)(await this._rpc("resources/read", { uri }));
|
|
110728
110768
|
}
|
|
110769
|
+
async listPrompts() {
|
|
110770
|
+
try {
|
|
110771
|
+
const res = await this._rpc("prompts/list", {});
|
|
110772
|
+
return Array.isArray(res?.prompts) ? res.prompts : [];
|
|
110773
|
+
} catch {
|
|
110774
|
+
return [];
|
|
110775
|
+
}
|
|
110776
|
+
}
|
|
110777
|
+
async getPrompt(name, args) {
|
|
110778
|
+
const params = { name };
|
|
110779
|
+
if (Object.keys(args).length)
|
|
110780
|
+
params.arguments = args;
|
|
110781
|
+
return (0, client_1.flattenPromptMessages)(await this._rpc("prompts/get", params));
|
|
110782
|
+
}
|
|
110729
110783
|
async callTool(name, args) {
|
|
110730
110784
|
const result = await this._rpc("tools/call", { name, arguments: args });
|
|
110731
110785
|
if (!result)
|
|
@@ -110872,6 +110926,20 @@ var require_sseClient = __commonJS({
|
|
|
110872
110926
|
async readResource(uri) {
|
|
110873
110927
|
return (0, client_1.flattenResourceContents)(await this._rpc("resources/read", { uri }));
|
|
110874
110928
|
}
|
|
110929
|
+
async listPrompts() {
|
|
110930
|
+
try {
|
|
110931
|
+
const res = await this._rpc("prompts/list", {});
|
|
110932
|
+
return Array.isArray(res?.prompts) ? res.prompts : [];
|
|
110933
|
+
} catch {
|
|
110934
|
+
return [];
|
|
110935
|
+
}
|
|
110936
|
+
}
|
|
110937
|
+
async getPrompt(name, args) {
|
|
110938
|
+
const params = { name };
|
|
110939
|
+
if (Object.keys(args).length)
|
|
110940
|
+
params.arguments = args;
|
|
110941
|
+
return (0, client_1.flattenPromptMessages)(await this._rpc("prompts/get", params));
|
|
110942
|
+
}
|
|
110875
110943
|
async callTool(name, args) {
|
|
110876
110944
|
const result = await this._rpc("tools/call", { name, arguments: args });
|
|
110877
110945
|
if (!result)
|
|
@@ -111216,6 +111284,7 @@ var require_manager = __commonJS({
|
|
|
111216
111284
|
constructor() {
|
|
111217
111285
|
this._clients = /* @__PURE__ */ new Map();
|
|
111218
111286
|
this._toolMap = /* @__PURE__ */ new Map();
|
|
111287
|
+
this._promptCache = /* @__PURE__ */ new Map();
|
|
111219
111288
|
this._configs = /* @__PURE__ */ new Map();
|
|
111220
111289
|
this._errors = /* @__PURE__ */ new Map();
|
|
111221
111290
|
this._needsAuth = /* @__PURE__ */ new Map();
|
|
@@ -111383,6 +111452,75 @@ var require_manager = __commonJS({
|
|
|
111383
111452
|
clearTimeout(timer);
|
|
111384
111453
|
}
|
|
111385
111454
|
}
|
|
111455
|
+
/**
|
|
111456
|
+
* Prompt metadata for one connected server. Fetched once per connection and
|
|
111457
|
+
* cached — including an empty list (server has no prompts capability), so the
|
|
111458
|
+
* `/` menu does not re-ask a server on every keystroke; reconnecting clears
|
|
111459
|
+
* the entry. Returns [] for a server that is not connected.
|
|
111460
|
+
*/
|
|
111461
|
+
async promptsFor(server) {
|
|
111462
|
+
const cached = this._promptCache.get(server);
|
|
111463
|
+
if (cached)
|
|
111464
|
+
return cached;
|
|
111465
|
+
const client = this._clients.get(server);
|
|
111466
|
+
if (!client)
|
|
111467
|
+
return [];
|
|
111468
|
+
const list = await client.listPrompts();
|
|
111469
|
+
this._promptCache.set(server, list);
|
|
111470
|
+
return list;
|
|
111471
|
+
}
|
|
111472
|
+
/** Prompts across connected, enabled servers, tagged with the server they came from. */
|
|
111473
|
+
async listPrompts(server) {
|
|
111474
|
+
const out = [];
|
|
111475
|
+
for (const name of this._clients.keys()) {
|
|
111476
|
+
if (server && name !== server)
|
|
111477
|
+
continue;
|
|
111478
|
+
for (const p of await this.promptsFor(name))
|
|
111479
|
+
out.push({ ...p, server: name });
|
|
111480
|
+
}
|
|
111481
|
+
return out;
|
|
111482
|
+
}
|
|
111483
|
+
/**
|
|
111484
|
+
* Expand one prompt to text. Positional values map, in order, onto the
|
|
111485
|
+
* arguments the server declared in prompts/list — the same positional form
|
|
111486
|
+
* Claude Code accepts (`/mcp__server__prompt first second`). Validation runs
|
|
111487
|
+
* here, before the request, so mistakes read as sentences instead of raw
|
|
111488
|
+
* JSON-RPC errors; the request itself is bounded by the same 60s timeout the
|
|
111489
|
+
* resource reader uses.
|
|
111490
|
+
*/
|
|
111491
|
+
async getPrompt(server, name, values = []) {
|
|
111492
|
+
const client = this._clients.get(server);
|
|
111493
|
+
if (!client)
|
|
111494
|
+
throw new Error(`No connected MCP server named "${server}". Connected: ${[...this._clients.keys()].join(", ") || "(none)"}`);
|
|
111495
|
+
const list = await this.promptsFor(server);
|
|
111496
|
+
const meta = list.find((p) => p.name === name);
|
|
111497
|
+
if (!meta) {
|
|
111498
|
+
throw new Error(`No MCP prompt named "${name}" on server "${server}"${list.length ? ` (it offers: ${list.map((p) => p.name).join(", ")})` : ""}.`);
|
|
111499
|
+
}
|
|
111500
|
+
const declared = meta.arguments ?? [];
|
|
111501
|
+
if (values.length > declared.length) {
|
|
111502
|
+
throw new Error(`MCP prompt "${server}:${name}" takes ${declared.length} argument(s)${declared.length ? ` (${declared.map((a) => a.name).join(", ")})` : ""} \u2014 got ${values.length}.`);
|
|
111503
|
+
}
|
|
111504
|
+
const args = {};
|
|
111505
|
+
declared.forEach((a, i2) => {
|
|
111506
|
+
const v = values[i2];
|
|
111507
|
+
if (v !== void 0 && v !== "")
|
|
111508
|
+
args[a.name] = v;
|
|
111509
|
+
});
|
|
111510
|
+
const missing = declared.filter((a) => a.required && args[a.name] === void 0);
|
|
111511
|
+
if (missing.length)
|
|
111512
|
+
throw new Error(`MCP prompt "${server}:${name}" is missing required argument(s): ${missing.map((a) => a.name).join(", ")}.`);
|
|
111513
|
+
let timer;
|
|
111514
|
+
const timeout = new Promise((_2, rej) => {
|
|
111515
|
+
timer = setTimeout(() => rej(new Error(`MCP prompt ${server}:${name} timed out after 60s`)), 6e4);
|
|
111516
|
+
});
|
|
111517
|
+
try {
|
|
111518
|
+
return await Promise.race([client.getPrompt(name, args), timeout]);
|
|
111519
|
+
} finally {
|
|
111520
|
+
if (timer)
|
|
111521
|
+
clearTimeout(timer);
|
|
111522
|
+
}
|
|
111523
|
+
}
|
|
111386
111524
|
/** True if this tool name belongs to an MCP server. */
|
|
111387
111525
|
isMcpTool(name) {
|
|
111388
111526
|
return this._toolMap.has(name);
|
|
@@ -111493,6 +111631,7 @@ var require_manager = __commonJS({
|
|
|
111493
111631
|
if (this._toolMap.get(key) === name)
|
|
111494
111632
|
this._toolMap.delete(key);
|
|
111495
111633
|
}
|
|
111634
|
+
this._promptCache.delete(name);
|
|
111496
111635
|
this.stats.reset();
|
|
111497
111636
|
}
|
|
111498
111637
|
// ─── Config file persistence (for the management UI) ──────────────────────────
|
|
@@ -141804,8 +141943,8 @@ var require_strip = __commonJS({
|
|
|
141804
141943
|
var require_src4 = __commonJS({
|
|
141805
141944
|
"../../node_modules/.pnpm/sisteransi@1.0.5/node_modules/sisteransi/src/index.js"(exports2, module2) {
|
|
141806
141945
|
"use strict";
|
|
141807
|
-
var
|
|
141808
|
-
var CSI2 = `${
|
|
141946
|
+
var ESC4 = "\x1B";
|
|
141947
|
+
var CSI2 = `${ESC4}[`;
|
|
141809
141948
|
var beep2 = "\x07";
|
|
141810
141949
|
var cursor = {
|
|
141811
141950
|
to(x2, y) {
|
|
@@ -141834,8 +141973,8 @@ var require_src4 = __commonJS({
|
|
|
141834
141973
|
left: `${CSI2}G`,
|
|
141835
141974
|
hide: `${CSI2}?25l`,
|
|
141836
141975
|
show: `${CSI2}?25h`,
|
|
141837
|
-
save: `${
|
|
141838
|
-
restore: `${
|
|
141976
|
+
save: `${ESC4}7`,
|
|
141977
|
+
restore: `${ESC4}8`
|
|
141839
141978
|
};
|
|
141840
141979
|
var scroll = {
|
|
141841
141980
|
up: (count = 1) => `${CSI2}S`.repeat(count),
|
|
@@ -157427,7 +157566,9 @@ function reserveBlockRows(previous, showing) {
|
|
|
157427
157566
|
function drainBlockRows(previous, printedRows) {
|
|
157428
157567
|
return Math.max(0, previous - Math.max(0, printedRows));
|
|
157429
157568
|
}
|
|
157430
|
-
|
|
157569
|
+
function replayReserveRows(slack, liveRows, pendingRows = 0) {
|
|
157570
|
+
return Math.max(Math.max(0, liveRows), Math.max(0, slack) - Math.max(0, pendingRows));
|
|
157571
|
+
}
|
|
157431
157572
|
function fillerRowCount(rowsAlreadyPrinted, footerTextValue = "", columns = process.stdout.columns ?? 80, rows = process.stdout.rows, reservedRows = 0, headroom = 2) {
|
|
157432
157573
|
if (!rows)
|
|
157433
157574
|
return 0;
|
|
@@ -166669,6 +166810,208 @@ function askForTrust(workDir, signals) {
|
|
|
166669
166810
|
});
|
|
166670
166811
|
}
|
|
166671
166812
|
|
|
166813
|
+
// src/ui/inputReports.ts
|
|
166814
|
+
var ESC3 = "\x1B";
|
|
166815
|
+
var BEL3 = "\x07";
|
|
166816
|
+
var REPORT_DEADLINE_MS = 120;
|
|
166817
|
+
var OSC_CAP = 4096;
|
|
166818
|
+
function newInputReportState() {
|
|
166819
|
+
return { pending: "", oscSkipLeft: 0 };
|
|
166820
|
+
}
|
|
166821
|
+
function filterInput(state, chunk, opts = {}) {
|
|
166822
|
+
const s2 = state.pending + chunk;
|
|
166823
|
+
state.pending = "";
|
|
166824
|
+
let out = "";
|
|
166825
|
+
let i2 = 0;
|
|
166826
|
+
if (state.oscSkipLeft > 0) {
|
|
166827
|
+
let j = i2;
|
|
166828
|
+
let terminated = false;
|
|
166829
|
+
while (j < s2.length) {
|
|
166830
|
+
if (s2[j] === BEL3) {
|
|
166831
|
+
terminated = true;
|
|
166832
|
+
j += 1;
|
|
166833
|
+
break;
|
|
166834
|
+
}
|
|
166835
|
+
if (s2[j] === ESC3 && s2[j + 1] === "\\") {
|
|
166836
|
+
terminated = true;
|
|
166837
|
+
j += 2;
|
|
166838
|
+
break;
|
|
166839
|
+
}
|
|
166840
|
+
if (s2[j] === ESC3 && j === s2.length - 1)
|
|
166841
|
+
break;
|
|
166842
|
+
j += 1;
|
|
166843
|
+
}
|
|
166844
|
+
const split = !terminated && j < s2.length && s2[j] === ESC3;
|
|
166845
|
+
if (terminated)
|
|
166846
|
+
state.oscSkipLeft = 0;
|
|
166847
|
+
else
|
|
166848
|
+
state.oscSkipLeft = Math.max(0, state.oscSkipLeft - (j - i2));
|
|
166849
|
+
if (split) {
|
|
166850
|
+
state.pending = s2.slice(j);
|
|
166851
|
+
return out;
|
|
166852
|
+
}
|
|
166853
|
+
i2 = j;
|
|
166854
|
+
}
|
|
166855
|
+
while (i2 < s2.length) {
|
|
166856
|
+
if (s2[i2] !== ESC3) {
|
|
166857
|
+
out += s2[i2];
|
|
166858
|
+
i2 += 1;
|
|
166859
|
+
continue;
|
|
166860
|
+
}
|
|
166861
|
+
if (i2 === s2.length - 1) {
|
|
166862
|
+
out += ESC3;
|
|
166863
|
+
i2 += 1;
|
|
166864
|
+
continue;
|
|
166865
|
+
}
|
|
166866
|
+
const next = s2[i2 + 1];
|
|
166867
|
+
if (next === "]") {
|
|
166868
|
+
const end = oscEnd(s2, i2 + 2);
|
|
166869
|
+
if (end >= 0) {
|
|
166870
|
+
i2 = end;
|
|
166871
|
+
continue;
|
|
166872
|
+
}
|
|
166873
|
+
if (s2.length - (i2 + 2) > OSC_CAP) {
|
|
166874
|
+
state.oscSkipLeft = OSC_CAP;
|
|
166875
|
+
i2 = s2.length;
|
|
166876
|
+
continue;
|
|
166877
|
+
}
|
|
166878
|
+
state.pending = s2.slice(i2);
|
|
166879
|
+
break;
|
|
166880
|
+
}
|
|
166881
|
+
if (next === "[") {
|
|
166882
|
+
const r2 = scanCsi(s2, i2, opts);
|
|
166883
|
+
if (r2.kind === "hold") {
|
|
166884
|
+
state.pending = s2.slice(i2);
|
|
166885
|
+
break;
|
|
166886
|
+
}
|
|
166887
|
+
if (r2.kind === "pass")
|
|
166888
|
+
out += s2.slice(i2, r2.end);
|
|
166889
|
+
i2 = r2.end;
|
|
166890
|
+
continue;
|
|
166891
|
+
}
|
|
166892
|
+
out += ESC3 + next;
|
|
166893
|
+
i2 += 2;
|
|
166894
|
+
}
|
|
166895
|
+
return out;
|
|
166896
|
+
}
|
|
166897
|
+
function releasePendingOnDeadline(state, _opts = {}) {
|
|
166898
|
+
const held = state.pending;
|
|
166899
|
+
state.pending = "";
|
|
166900
|
+
if (held === "")
|
|
166901
|
+
return "";
|
|
166902
|
+
if (held.startsWith(ESC3 + "]"))
|
|
166903
|
+
return "";
|
|
166904
|
+
if (held.startsWith(ESC3 + "[")) {
|
|
166905
|
+
const rest = held.slice(2);
|
|
166906
|
+
if (rest.startsWith("M") || rest.startsWith("<"))
|
|
166907
|
+
return "";
|
|
166908
|
+
return ESC3;
|
|
166909
|
+
}
|
|
166910
|
+
return "";
|
|
166911
|
+
}
|
|
166912
|
+
function scanCsi(s2, start, opts) {
|
|
166913
|
+
let j = start + 2;
|
|
166914
|
+
while (j < s2.length) {
|
|
166915
|
+
const c = s2.charCodeAt(j);
|
|
166916
|
+
if (c >= 64 && c <= 126)
|
|
166917
|
+
break;
|
|
166918
|
+
if (c >= 48 && c <= 63) {
|
|
166919
|
+
j += 1;
|
|
166920
|
+
continue;
|
|
166921
|
+
}
|
|
166922
|
+
if (c >= 32 && c <= 47) {
|
|
166923
|
+
j += 1;
|
|
166924
|
+
continue;
|
|
166925
|
+
}
|
|
166926
|
+
return { kind: "drop", end: start + 2 };
|
|
166927
|
+
}
|
|
166928
|
+
if (j >= s2.length)
|
|
166929
|
+
return { kind: "hold" };
|
|
166930
|
+
const final = s2[j];
|
|
166931
|
+
const body = s2.slice(start + 2, j);
|
|
166932
|
+
const seqEnd = j + 1;
|
|
166933
|
+
if (final === "M" && body === "") {
|
|
166934
|
+
if (s2.length < seqEnd + 3)
|
|
166935
|
+
return { kind: "hold" };
|
|
166936
|
+
return opts.passMouse ? { kind: "pass", end: seqEnd + 3 } : { kind: "drop", end: seqEnd + 3 };
|
|
166937
|
+
}
|
|
166938
|
+
if (body.startsWith("<")) {
|
|
166939
|
+
return opts.passMouse ? { kind: "pass", end: seqEnd } : { kind: "drop", end: seqEnd };
|
|
166940
|
+
}
|
|
166941
|
+
if (/^[?>=!]/.test(body))
|
|
166942
|
+
return { kind: "drop", end: seqEnd };
|
|
166943
|
+
if (body === "" && (final === "I" || final === "O"))
|
|
166944
|
+
return { kind: "drop", end: seqEnd };
|
|
166945
|
+
if (final === "R" && /^\d+;\d+$/.test(body))
|
|
166946
|
+
return { kind: "drop", end: seqEnd };
|
|
166947
|
+
return { kind: "pass", end: seqEnd };
|
|
166948
|
+
}
|
|
166949
|
+
function oscEnd(s2, from) {
|
|
166950
|
+
for (let i2 = from; i2 < s2.length; i2 += 1) {
|
|
166951
|
+
if (s2[i2] === BEL3)
|
|
166952
|
+
return i2 + 1;
|
|
166953
|
+
if (s2[i2] === ESC3 && s2[i2 + 1] === "\\")
|
|
166954
|
+
return i2 + 2;
|
|
166955
|
+
}
|
|
166956
|
+
return -1;
|
|
166957
|
+
}
|
|
166958
|
+
var mousePassthrough = () => false;
|
|
166959
|
+
var installed = false;
|
|
166960
|
+
function setMousePassthrough(fn) {
|
|
166961
|
+
mousePassthrough = fn;
|
|
166962
|
+
}
|
|
166963
|
+
function installInputReportFilter(stream = process.stdin) {
|
|
166964
|
+
const isDefault = stream === process.stdin;
|
|
166965
|
+
if (isDefault && installed)
|
|
166966
|
+
return () => {
|
|
166967
|
+
};
|
|
166968
|
+
if (isDefault)
|
|
166969
|
+
installed = true;
|
|
166970
|
+
const stdin = stream;
|
|
166971
|
+
const origRead = stdin.read.bind(stdin);
|
|
166972
|
+
const state = newInputReportState();
|
|
166973
|
+
let outbox = "";
|
|
166974
|
+
let timer = null;
|
|
166975
|
+
const clearTimer = () => {
|
|
166976
|
+
if (timer) {
|
|
166977
|
+
clearTimeout(timer);
|
|
166978
|
+
timer = null;
|
|
166979
|
+
}
|
|
166980
|
+
};
|
|
166981
|
+
const onDeadline = () => {
|
|
166982
|
+
timer = null;
|
|
166983
|
+
outbox += releasePendingOnDeadline(state, { passMouse: mousePassthrough() });
|
|
166984
|
+
stdin.emit("readable");
|
|
166985
|
+
};
|
|
166986
|
+
stdin.read = function patchedRead(...args) {
|
|
166987
|
+
if (args.length > 0)
|
|
166988
|
+
return origRead(...args);
|
|
166989
|
+
let chunk;
|
|
166990
|
+
while ((chunk = origRead()) !== null && chunk !== void 0) {
|
|
166991
|
+
const s2 = typeof chunk === "string" ? chunk : Buffer.from(chunk).toString("utf8");
|
|
166992
|
+
outbox += filterInput(state, s2, { passMouse: mousePassthrough() });
|
|
166993
|
+
}
|
|
166994
|
+
if (state.pending !== "") {
|
|
166995
|
+
clearTimer();
|
|
166996
|
+
timer = setTimeout(onDeadline, REPORT_DEADLINE_MS);
|
|
166997
|
+
timer.unref?.();
|
|
166998
|
+
} else {
|
|
166999
|
+
clearTimer();
|
|
167000
|
+
}
|
|
167001
|
+
if (outbox === "")
|
|
167002
|
+
return null;
|
|
167003
|
+
const out = outbox;
|
|
167004
|
+
outbox = "";
|
|
167005
|
+
return out;
|
|
167006
|
+
};
|
|
167007
|
+
return () => {
|
|
167008
|
+
clearTimer();
|
|
167009
|
+
stdin.read = origRead;
|
|
167010
|
+
if (isDefault)
|
|
167011
|
+
installed = false;
|
|
167012
|
+
};
|
|
167013
|
+
}
|
|
167014
|
+
|
|
166672
167015
|
// src/ui/inkTerminal.tsx
|
|
166673
167016
|
var import_react36 = __toESM(require_react(), 1);
|
|
166674
167017
|
|
|
@@ -166906,6 +167249,32 @@ function skillEntries(skills, builtins = BUILTIN_SLASH_COMMANDS) {
|
|
|
166906
167249
|
}
|
|
166907
167250
|
return out;
|
|
166908
167251
|
}
|
|
167252
|
+
function promptEntries(prompts2, builtins = BUILTIN_SLASH_COMMANDS) {
|
|
167253
|
+
const taken = /* @__PURE__ */ new Set();
|
|
167254
|
+
for (const b of builtins) {
|
|
167255
|
+
taken.add(b.name);
|
|
167256
|
+
for (const a of b.aliases ?? [])
|
|
167257
|
+
taken.add(a);
|
|
167258
|
+
}
|
|
167259
|
+
const out = [];
|
|
167260
|
+
for (const p of prompts2) {
|
|
167261
|
+
const name = `${p.server}:${p.name}`;
|
|
167262
|
+
if (taken.has(name))
|
|
167263
|
+
continue;
|
|
167264
|
+
taken.add(name);
|
|
167265
|
+
const args = p.arguments ?? [];
|
|
167266
|
+
const description = (p.description ?? "").replace(/\s+/g, " ").trim() || `MCP prompt from ${p.server}`;
|
|
167267
|
+
out.push({
|
|
167268
|
+
name,
|
|
167269
|
+
description,
|
|
167270
|
+
argHint: args.length ? args.map((a) => a.required ? `<${a.name}>` : `[${a.name}]`).join(" ") : void 0,
|
|
167271
|
+
requiresArg: args.some((a) => a.required) || void 0,
|
|
167272
|
+
kind: "mcp",
|
|
167273
|
+
source: p.server
|
|
167274
|
+
});
|
|
167275
|
+
}
|
|
167276
|
+
return out;
|
|
167277
|
+
}
|
|
166909
167278
|
function matchScore(query, name, aliases, description) {
|
|
166910
167279
|
if (!query)
|
|
166911
167280
|
return 0;
|
|
@@ -166946,7 +167315,7 @@ function slashQuery(line, cursor) {
|
|
|
166946
167315
|
return null;
|
|
166947
167316
|
if (line.includes("\n"))
|
|
166948
167317
|
return null;
|
|
166949
|
-
const m2 = /^\/([\w
|
|
167318
|
+
const m2 = /^\/([\w:-]*)$/.exec(line);
|
|
166950
167319
|
if (!m2)
|
|
166951
167320
|
return null;
|
|
166952
167321
|
if (cursor < 1)
|
|
@@ -167756,7 +168125,7 @@ function describeOpen(spec, target, cwd2) {
|
|
|
167756
168125
|
// src/ui/fileMention.ts
|
|
167757
168126
|
import * as fs26 from "fs";
|
|
167758
168127
|
import * as path26 from "path";
|
|
167759
|
-
import { execFileSync as execFileSync4 } from "child_process";
|
|
168128
|
+
import { execFile, execFileSync as execFileSync4 } from "child_process";
|
|
167760
168129
|
|
|
167761
168130
|
// src/ui/contextFiles.ts
|
|
167762
168131
|
import * as fs25 from "fs";
|
|
@@ -167971,6 +168340,9 @@ var IGNORED_DIRS = /* @__PURE__ */ new Set([
|
|
|
167971
168340
|
]);
|
|
167972
168341
|
var MAX_INDEXED = 5e4;
|
|
167973
168342
|
function listProjectFiles(cwd2) {
|
|
168343
|
+
return listProjectFilesFrom(cwd2).files;
|
|
168344
|
+
}
|
|
168345
|
+
function listProjectFilesFrom(cwd2) {
|
|
167974
168346
|
let files = null;
|
|
167975
168347
|
try {
|
|
167976
168348
|
const out = execFileSync4("git", ["-C", cwd2, "ls-files", "-co", "--exclude-standard", "-z"], {
|
|
@@ -167982,34 +168354,41 @@ function listProjectFiles(cwd2) {
|
|
|
167982
168354
|
files = [...new Set(out.split("\0").filter(Boolean))];
|
|
167983
168355
|
} catch {
|
|
167984
168356
|
}
|
|
168357
|
+
const source2 = files ? "git" : "walk";
|
|
167985
168358
|
if (!files)
|
|
167986
168359
|
files = walk(cwd2);
|
|
167987
|
-
return files.filter((f3) => !/\s/.test(f3)).slice(0, MAX_INDEXED);
|
|
168360
|
+
return { files: files.filter((f3) => !/\s/.test(f3)).slice(0, MAX_INDEXED), source: source2 };
|
|
167988
168361
|
}
|
|
167989
|
-
function
|
|
167990
|
-
const
|
|
167991
|
-
|
|
167992
|
-
|
|
167993
|
-
|
|
168362
|
+
function* walkEntries(root) {
|
|
168363
|
+
const queue = [{ dir: root, depth: 0 }];
|
|
168364
|
+
for (let i2 = 0; i2 < queue.length; i2++) {
|
|
168365
|
+
const { dir, depth } = queue[i2];
|
|
168366
|
+
if (depth > 8)
|
|
168367
|
+
continue;
|
|
167994
168368
|
let entries;
|
|
167995
168369
|
try {
|
|
167996
168370
|
entries = fs26.readdirSync(dir, { withFileTypes: true });
|
|
167997
168371
|
} catch {
|
|
167998
|
-
|
|
168372
|
+
continue;
|
|
167999
168373
|
}
|
|
168000
168374
|
for (const e2 of entries) {
|
|
168001
|
-
if (out.length >= MAX_INDEXED)
|
|
168002
|
-
return;
|
|
168003
168375
|
const full = path26.join(dir, e2.name);
|
|
168004
168376
|
if (e2.isDirectory()) {
|
|
168005
168377
|
if (!IGNORED_DIRS.has(e2.name) && !e2.isSymbolicLink())
|
|
168006
|
-
|
|
168378
|
+
queue.push({ dir: full, depth: depth + 1 });
|
|
168007
168379
|
} else if (e2.isFile()) {
|
|
168008
|
-
|
|
168380
|
+
yield path26.relative(root, full).split(path26.sep).join("/");
|
|
168009
168381
|
}
|
|
168010
168382
|
}
|
|
168011
|
-
}
|
|
168012
|
-
|
|
168383
|
+
}
|
|
168384
|
+
}
|
|
168385
|
+
function walk(root) {
|
|
168386
|
+
const out = [];
|
|
168387
|
+
for (const f3 of walkEntries(root)) {
|
|
168388
|
+
out.push(f3);
|
|
168389
|
+
if (out.length >= MAX_INDEXED)
|
|
168390
|
+
break;
|
|
168391
|
+
}
|
|
168013
168392
|
return out;
|
|
168014
168393
|
}
|
|
168015
168394
|
function buildIndex(files) {
|
|
@@ -168021,20 +168400,111 @@ function buildIndex(files) {
|
|
|
168021
168400
|
}
|
|
168022
168401
|
return [...dirs, ...files].sort();
|
|
168023
168402
|
}
|
|
168403
|
+
var GIT_CACHE_MS = 5e3;
|
|
168404
|
+
var WALK_CACHE_MS = 6e4;
|
|
168024
168405
|
var cache3 = null;
|
|
168025
|
-
var CACHE_MS = 5e3;
|
|
168026
168406
|
var excludedPatterns = [];
|
|
168407
|
+
var excludedKey = "[]";
|
|
168027
168408
|
function setExcludedPatterns(patterns) {
|
|
168028
168409
|
excludedPatterns = [...patterns];
|
|
168029
|
-
|
|
168410
|
+
excludedKey = JSON.stringify(excludedPatterns);
|
|
168411
|
+
}
|
|
168412
|
+
function derivedIndex(raw) {
|
|
168413
|
+
return buildIndex(raw.filter((f3) => !isExcluded(f3, excludedPatterns)));
|
|
168030
168414
|
}
|
|
168031
168415
|
function projectIndex(cwd2, now = Date.now()) {
|
|
168032
|
-
if (cache3 && cache3.cwd === cwd2 && now - cache3.at <
|
|
168416
|
+
if (cache3 && cache3.cwd === cwd2 && now - cache3.at < cache3.ttl) {
|
|
168417
|
+
if (cache3.patterns !== excludedKey)
|
|
168418
|
+
cache3 = { ...cache3, patterns: excludedKey, index: derivedIndex(cache3.raw) };
|
|
168033
168419
|
return cache3.index;
|
|
168034
|
-
|
|
168035
|
-
const
|
|
168036
|
-
cache3 = {
|
|
168037
|
-
|
|
168420
|
+
}
|
|
168421
|
+
const { files, source: source2 } = listProjectFilesFrom(cwd2);
|
|
168422
|
+
cache3 = {
|
|
168423
|
+
cwd: cwd2,
|
|
168424
|
+
at: now,
|
|
168425
|
+
ttl: source2 === "git" ? GIT_CACHE_MS : WALK_CACHE_MS,
|
|
168426
|
+
raw: files,
|
|
168427
|
+
patterns: excludedKey,
|
|
168428
|
+
index: derivedIndex(files)
|
|
168429
|
+
};
|
|
168430
|
+
return cache3.index;
|
|
168431
|
+
}
|
|
168432
|
+
var WALK_SLICE_MS = 8;
|
|
168433
|
+
var indexListener = null;
|
|
168434
|
+
function setMentionIndexListener(cb) {
|
|
168435
|
+
indexListener = cb;
|
|
168436
|
+
}
|
|
168437
|
+
var building = null;
|
|
168438
|
+
function walkInSlices(root, job, done) {
|
|
168439
|
+
const entries = walkEntries(root);
|
|
168440
|
+
const out = [];
|
|
168441
|
+
const step = () => {
|
|
168442
|
+
if (job.cancelled)
|
|
168443
|
+
return;
|
|
168444
|
+
const t0 = Date.now();
|
|
168445
|
+
for (; ; ) {
|
|
168446
|
+
if (out.length >= MAX_INDEXED)
|
|
168447
|
+
return done(out);
|
|
168448
|
+
const next = entries.next();
|
|
168449
|
+
if (next.done)
|
|
168450
|
+
return done(out);
|
|
168451
|
+
out.push(next.value);
|
|
168452
|
+
if (Date.now() - t0 >= WALK_SLICE_MS)
|
|
168453
|
+
break;
|
|
168454
|
+
}
|
|
168455
|
+
setImmediate(step);
|
|
168456
|
+
};
|
|
168457
|
+
setImmediate(step);
|
|
168458
|
+
}
|
|
168459
|
+
function finishBuild(job, files, source2) {
|
|
168460
|
+
if (job.cancelled)
|
|
168461
|
+
return;
|
|
168462
|
+
if (building === job)
|
|
168463
|
+
building = null;
|
|
168464
|
+
const raw = files.filter((f3) => !/\s/.test(f3)).slice(0, MAX_INDEXED);
|
|
168465
|
+
cache3 = {
|
|
168466
|
+
cwd: job.cwd,
|
|
168467
|
+
at: Date.now(),
|
|
168468
|
+
ttl: source2 === "git" ? GIT_CACHE_MS : WALK_CACHE_MS,
|
|
168469
|
+
raw,
|
|
168470
|
+
patterns: excludedKey,
|
|
168471
|
+
index: derivedIndex(raw)
|
|
168472
|
+
};
|
|
168473
|
+
indexListener?.();
|
|
168474
|
+
}
|
|
168475
|
+
function primeMentionIndex(cwd2) {
|
|
168476
|
+
if (cache3 && cache3.cwd === cwd2 && Date.now() - cache3.at < cache3.ttl)
|
|
168477
|
+
return;
|
|
168478
|
+
if (building && building.cwd === cwd2 && !building.cancelled)
|
|
168479
|
+
return;
|
|
168480
|
+
if (building)
|
|
168481
|
+
building.cancelled = true;
|
|
168482
|
+
const job = { cwd: cwd2, cancelled: false };
|
|
168483
|
+
building = job;
|
|
168484
|
+
execFile("git", ["-C", cwd2, "ls-files", "-co", "--exclude-standard", "-z"], {
|
|
168485
|
+
encoding: "utf-8",
|
|
168486
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
168487
|
+
timeout: 5e3
|
|
168488
|
+
}, (err, stdout) => {
|
|
168489
|
+
if (job.cancelled)
|
|
168490
|
+
return;
|
|
168491
|
+
if (!err) {
|
|
168492
|
+
finishBuild(job, [...new Set(stdout.split("\0").filter(Boolean))], "git");
|
|
168493
|
+
return;
|
|
168494
|
+
}
|
|
168495
|
+
walkInSlices(cwd2, job, (files) => finishBuild(job, files, "walk"));
|
|
168496
|
+
});
|
|
168497
|
+
}
|
|
168498
|
+
function mentionIndexForRender(cwd2) {
|
|
168499
|
+
if (!cache3 || cache3.cwd !== cwd2) {
|
|
168500
|
+
primeMentionIndex(cwd2);
|
|
168501
|
+
return [];
|
|
168502
|
+
}
|
|
168503
|
+
if (cache3.patterns !== excludedKey)
|
|
168504
|
+
cache3 = { ...cache3, patterns: excludedKey, index: derivedIndex(cache3.raw) };
|
|
168505
|
+
if (Date.now() - cache3.at >= cache3.ttl)
|
|
168506
|
+
primeMentionIndex(cwd2);
|
|
168507
|
+
return cache3.index;
|
|
168038
168508
|
}
|
|
168039
168509
|
function subsequence(hay, needle) {
|
|
168040
168510
|
let i2 = 0;
|
|
@@ -168077,13 +168547,13 @@ function rankMentions(query, index, limit = 200) {
|
|
|
168077
168547
|
}
|
|
168078
168548
|
return index.map((p, i2) => ({ p, i: i2, s: score(p, q) })).filter((x2) => x2.s !== Infinity).sort((a, b) => a.s - b.s || a.p.length - b.p.length || a.i - b.i).slice(0, limit).map((x2) => x2.p);
|
|
168079
168549
|
}
|
|
168080
|
-
function computeMention(line, cursor,
|
|
168550
|
+
function computeMention(line, cursor, getIndex, dismissedFor) {
|
|
168081
168551
|
if (dismissedFor !== null && dismissedFor === line)
|
|
168082
168552
|
return null;
|
|
168083
168553
|
const at = mentionAt(line, cursor);
|
|
168084
168554
|
if (!at)
|
|
168085
168555
|
return null;
|
|
168086
|
-
const items = rankMentions(at.query,
|
|
168556
|
+
const items = rankMentions(at.query, getIndex());
|
|
168087
168557
|
return items.length ? { at, items } : null;
|
|
168088
168558
|
}
|
|
168089
168559
|
function decideMentionEnter(query, pick) {
|
|
@@ -168560,7 +169030,7 @@ function slashMenuView(p) {
|
|
|
168560
169030
|
return {
|
|
168561
169031
|
rows: shown.map((e2, i2) => {
|
|
168562
169032
|
const label = `/${e2.name}${e2.argHint ? " " + e2.argHint : ""}`;
|
|
168563
|
-
const tag = e2.kind === "skill" ? ` (${e2.source === "project" || !e2.source ? "skill" : e2.source + " skill"})` : "";
|
|
169033
|
+
const tag = e2.kind === "mcp" ? " (MCP)" : e2.kind === "skill" ? ` (${e2.source === "project" || !e2.source ? "skill" : e2.source + " skill"})` : "";
|
|
168564
169034
|
const alias = e2.aliases?.length ? ` (${e2.aliases.map((a) => "/" + a).join(", ")})` : "";
|
|
168565
169035
|
const seen = e2.recent ? " \xB7 recent" : "";
|
|
168566
169036
|
return {
|
|
@@ -168615,7 +169085,7 @@ function fullscreenView(p) {
|
|
|
168615
169085
|
function mentionMenuView(p) {
|
|
168616
169086
|
if (p.blocked)
|
|
168617
169087
|
return null;
|
|
168618
|
-
const m2 = computeMention(p.line, p.cursorPos,
|
|
169088
|
+
const m2 = computeMention(p.line, p.cursorPos, () => mentionIndexForRender(p.root), p.dismissedFor);
|
|
168619
169089
|
if (!m2)
|
|
168620
169090
|
return null;
|
|
168621
169091
|
const sel = Math.min(p.sel.query === m2.at.query ? p.sel.idx : 0, m2.items.length - 1);
|
|
@@ -168652,13 +169122,6 @@ function decideCtrlC(state) {
|
|
|
168652
169122
|
}
|
|
168653
169123
|
|
|
168654
169124
|
// src/ui/inkTerminal.tsx
|
|
168655
|
-
function fillerContent(rows) {
|
|
168656
|
-
if (rows <= 0)
|
|
168657
|
-
return "";
|
|
168658
|
-
if (rows === 1)
|
|
168659
|
-
return " ";
|
|
168660
|
-
return "\n".repeat(rows - 1);
|
|
168661
|
-
}
|
|
168662
169125
|
function isBusySlashCommand(line) {
|
|
168663
169126
|
return /^\/[a-z][\w-]*(\s|$)/.test(line.trim());
|
|
168664
169127
|
}
|
|
@@ -168811,12 +169274,12 @@ var App2 = ({ onReady }) => {
|
|
|
168811
169274
|
const mentionRootRef = (0, import_react36.useRef)(process.cwd());
|
|
168812
169275
|
const setMentionRoot = (0, import_react36.useCallback)((dir) => {
|
|
168813
169276
|
mentionRootRef.current = dir;
|
|
168814
|
-
|
|
168815
|
-
|
|
168816
|
-
|
|
168817
|
-
|
|
168818
|
-
|
|
168819
|
-
|
|
169277
|
+
primeMentionIndex(dir);
|
|
169278
|
+
}, []);
|
|
169279
|
+
const [, bumpMentionIndex] = (0, import_react36.useState)(0);
|
|
169280
|
+
import_react36.default.useEffect(() => {
|
|
169281
|
+
setMentionIndexListener(() => bumpMentionIndex((n) => n + 1));
|
|
169282
|
+
return () => setMentionIndexListener(null);
|
|
168820
169283
|
}, []);
|
|
168821
169284
|
const setSlashEntries = (0, import_react36.useCallback)((entries) => {
|
|
168822
169285
|
slashEntriesRef.current = entries;
|
|
@@ -169259,7 +169722,7 @@ var App2 = ({ onReady }) => {
|
|
|
169259
169722
|
}
|
|
169260
169723
|
}
|
|
169261
169724
|
}
|
|
169262
|
-
const mention = askResolverRef.current || choiceRef.current || searchRef.current || historyRef.current.browsing || busyRef.current ? null : computeMention(lineRef.current, cursorRef.current,
|
|
169725
|
+
const mention = askResolverRef.current || choiceRef.current || searchRef.current || historyRef.current.browsing || busyRef.current ? null : computeMention(lineRef.current, cursorRef.current, () => mentionIndexForRender(mentionRootRef.current), mentionDismissedRef.current);
|
|
169263
169726
|
if (mention) {
|
|
169264
169727
|
const sel = mentionSelRef.current.query === mention.at.query ? mentionSelRef.current.idx : 0;
|
|
169265
169728
|
const pick = mention.items[Math.min(sel, mention.items.length - 1)];
|
|
@@ -169555,19 +170018,8 @@ var App2 = ({ onReady }) => {
|
|
|
169555
170018
|
const liveRows = liveRef.current ? rowsOccupied(liveRef.current, columns) : 0;
|
|
169556
170019
|
const footer2 = footerRef.current ? footerText(footerRef.current) : "";
|
|
169557
170020
|
const slack = fillerRowCount(printedRows, footer2, columns, void 0, liveRows, 1);
|
|
169558
|
-
|
|
169559
|
-
|
|
169560
|
-
const filler = fillerRowCount(
|
|
169561
|
-
printedRows,
|
|
169562
|
-
footer2,
|
|
169563
|
-
columns,
|
|
169564
|
-
void 0,
|
|
169565
|
-
Math.max(liveRows, seed) + Math.max(0, pendingRows),
|
|
169566
|
-
1
|
|
169567
|
-
);
|
|
169568
|
-
if (filler <= 0)
|
|
169569
|
-
return withoutOldFiller;
|
|
169570
|
-
return [...withoutOldFiller, { id: idCounter++, content: fillerContent(filler), isFiller: true }];
|
|
170021
|
+
liveReserveRef.current = replayReserveRows(slack, liveRows, pendingRows);
|
|
170022
|
+
return withoutOldFiller;
|
|
169571
170023
|
});
|
|
169572
170024
|
}, []);
|
|
169573
170025
|
const forceFullRedraw = (0, import_react36.useCallback)(() => {
|
|
@@ -169642,6 +170094,9 @@ var App2 = ({ onReady }) => {
|
|
|
169642
170094
|
if (fullscreenRef.current)
|
|
169643
170095
|
process.stdout.write(on ? MOUSE_ON : MOUSE_OFF);
|
|
169644
170096
|
}, []);
|
|
170097
|
+
import_react36.default.useEffect(() => {
|
|
170098
|
+
setMousePassthrough(() => fullscreenRef.current && mouseRef.current);
|
|
170099
|
+
}, []);
|
|
169645
170100
|
import_react36.default.useEffect(() => () => {
|
|
169646
170101
|
if (fullscreenRef.current) {
|
|
169647
170102
|
fullscreenRef.current = false;
|
|
@@ -169998,6 +170453,38 @@ var InkReadlineAdapter = class extends EventEmitter3 {
|
|
|
169998
170453
|
}
|
|
169999
170454
|
};
|
|
170000
170455
|
|
|
170456
|
+
// src/ui/mcpPrompt.ts
|
|
170457
|
+
function parseMcpPromptRef(cmd, serverNames) {
|
|
170458
|
+
const bare = cmd.startsWith("/") ? cmd.slice(1) : cmd;
|
|
170459
|
+
if (bare.startsWith("mcp__")) {
|
|
170460
|
+
const rest = bare.slice("mcp__".length);
|
|
170461
|
+
const candidates = serverNames.filter((s2) => rest.startsWith(s2 + "__")).sort((a, b) => b.length - a.length);
|
|
170462
|
+
const server = candidates[0];
|
|
170463
|
+
if (!server)
|
|
170464
|
+
return null;
|
|
170465
|
+
const name = rest.slice(server.length + 2);
|
|
170466
|
+
return name ? { server, name } : null;
|
|
170467
|
+
}
|
|
170468
|
+
const colon = bare.indexOf(":");
|
|
170469
|
+
if (colon > 0) {
|
|
170470
|
+
const server = bare.slice(0, colon);
|
|
170471
|
+
const name = bare.slice(colon + 1);
|
|
170472
|
+
if (name && serverNames.includes(server))
|
|
170473
|
+
return { server, name };
|
|
170474
|
+
}
|
|
170475
|
+
return null;
|
|
170476
|
+
}
|
|
170477
|
+
function splitPromptArgs(arg) {
|
|
170478
|
+
const out = [];
|
|
170479
|
+
const re = /"([^"]*)"|'([^']*)'|(\S+)/g;
|
|
170480
|
+
let m2;
|
|
170481
|
+
while (m2 = re.exec(arg)) {
|
|
170482
|
+
const v = m2[1] ?? m2[2] ?? m2[3];
|
|
170483
|
+
out.push(v);
|
|
170484
|
+
}
|
|
170485
|
+
return out;
|
|
170486
|
+
}
|
|
170487
|
+
|
|
170001
170488
|
// src/ui/recents.ts
|
|
170002
170489
|
import fs27 from "node:fs";
|
|
170003
170490
|
import os17 from "node:os";
|
|
@@ -173270,7 +173757,7 @@ function printHelp() {
|
|
|
173270
173757
|
["/skills", "List skills (.nexrall/skills/<name>/SKILL.md or .nexrall/commands/*.md) \u2014 the model can also auto-invoke these"],
|
|
173271
173758
|
["/commands", "List your custom commands (.nexrall/commands/*.md)"],
|
|
173272
173759
|
["/plugins", "List installed plugins (.nexrall/plugins/)"],
|
|
173273
|
-
["/mcp [name|verb]", "List servers; <name> inspects tools/latency; enable|disable persists, connect|disconnect lasts the session"],
|
|
173760
|
+
["/mcp [name|verb]", "List servers; <name> inspects tools/latency; enable|disable persists, connect|disconnect lasts the session; prompts lists /server:prompt templates"],
|
|
173274
173761
|
["/open <path[:line]>", 'Open a file in your editor (bare /open picks from files this session touched; finds "auth.ts" anywhere)'],
|
|
173275
173762
|
["/doctor", "Check Node, sign-in, network, terminal, MCP and storage; shows how to fix each problem"],
|
|
173276
173763
|
["/fullscreen", "Draw the session on the terminal's alternate screen: it re-wraps on resize and PgUp/PgDn page through it"],
|
|
@@ -173399,6 +173886,7 @@ function printSessions() {
|
|
|
173399
173886
|
console.log();
|
|
173400
173887
|
}
|
|
173401
173888
|
async function startChatSession(options) {
|
|
173889
|
+
installInputReportFilter();
|
|
173402
173890
|
if (options.bare)
|
|
173403
173891
|
setNoDiscovery(true);
|
|
173404
173892
|
_cliAgentTypes = (options.agents ?? []).map((a) => ({ ...a, source: "programmatic" }));
|
|
@@ -173968,13 +174456,32 @@ ${text}` : "");
|
|
|
173968
174456
|
console.log(paint.green(` \u2713 Saved to ${saved.scope} memory`) + paint.dim(` \u2014 ${saved.file}`) + (saved.superseded ? paint.dim(" (the older fact moved to Superseded)") : ""));
|
|
173969
174457
|
}
|
|
173970
174458
|
};
|
|
173971
|
-
|
|
174459
|
+
let mcpPromptList = [];
|
|
174460
|
+
const allSlashEntries = () => {
|
|
174461
|
+
const base = [...BUILTIN_SLASH_COMMANDS, ...skillEntries((0, import_code_core18.userInvokableSkills)(skills))];
|
|
174462
|
+
return [...base, ...promptEntries(mcpPromptList, base)];
|
|
174463
|
+
};
|
|
173972
174464
|
let slashRecents = loadRecents();
|
|
173973
174465
|
const syncSlashMenu = () => {
|
|
173974
174466
|
if (interactive)
|
|
173975
174467
|
getInkTerminal().setSlashEntries(orderByRecents(allSlashEntries(), slashRecents));
|
|
173976
174468
|
};
|
|
174469
|
+
const refreshMcpPrompts = async () => {
|
|
174470
|
+
if (!_mcpManager)
|
|
174471
|
+
return;
|
|
174472
|
+
let list;
|
|
174473
|
+
try {
|
|
174474
|
+
list = await _mcpManager.listPrompts();
|
|
174475
|
+
} catch {
|
|
174476
|
+
return;
|
|
174477
|
+
}
|
|
174478
|
+
if (JSON.stringify(list) === JSON.stringify(mcpPromptList))
|
|
174479
|
+
return;
|
|
174480
|
+
mcpPromptList = list;
|
|
174481
|
+
syncSlashMenu();
|
|
174482
|
+
};
|
|
173977
174483
|
syncSlashMenu();
|
|
174484
|
+
void mcpStarted.then(() => refreshMcpPrompts());
|
|
173978
174485
|
if (interactive)
|
|
173979
174486
|
getInkTerminal().setMentionRoot(workDir);
|
|
173980
174487
|
const doRewind = (id) => {
|
|
@@ -174267,6 +174774,7 @@ ${text}` : "");
|
|
|
174267
174774
|
}
|
|
174268
174775
|
}
|
|
174269
174776
|
}
|
|
174777
|
+
void refreshMcpPrompts();
|
|
174270
174778
|
const outcome = {};
|
|
174271
174779
|
if (error !== void 0)
|
|
174272
174780
|
outcome.error = error;
|
|
@@ -176150,6 +176658,26 @@ ${text}
|
|
|
176150
176658
|
rl.prompt();
|
|
176151
176659
|
return;
|
|
176152
176660
|
}
|
|
176661
|
+
const promptArg = /^prompts?(?:\s+(\S+))?$/i.exec(arg.trim());
|
|
176662
|
+
if (promptArg) {
|
|
176663
|
+
await refreshMcpPrompts();
|
|
176664
|
+
const rows = promptArg[1] ? mcpPromptList.filter((p) => p.server === promptArg[1]) : mcpPromptList;
|
|
176665
|
+
console.log(paint.bold(" MCP prompts:"));
|
|
176666
|
+
if (!rows.length) {
|
|
176667
|
+
console.log(" " + paint.dim(promptArg[1] ? `No prompts offered by "${promptArg[1]}".` : "No prompts offered by the connected servers."));
|
|
176668
|
+
} else {
|
|
176669
|
+
const width = Math.max(...rows.map((p) => `${p.server}:${p.name}`.length));
|
|
176670
|
+
for (const p of rows) {
|
|
176671
|
+
const args = (p.arguments ?? []).map((a) => a.required ? `<${a.name}>` : `[${a.name}]`).join(" ");
|
|
176672
|
+
console.log(" " + paint.cyan(`/${p.server}:${p.name}`.padEnd(width + 1)) + " " + (args ? paint.yellow(args) + " " : "") + paint.dim((p.description ?? "").replace(/\s+/g, " ").trim() || `MCP prompt from ${p.server}`));
|
|
176673
|
+
}
|
|
176674
|
+
console.log();
|
|
176675
|
+
console.log(" " + paint.dim("Run one: type /server:prompt with its arguments (positional; quotes keep spaces together)."));
|
|
176676
|
+
}
|
|
176677
|
+
console.log();
|
|
176678
|
+
rl.prompt();
|
|
176679
|
+
return;
|
|
176680
|
+
}
|
|
176153
176681
|
console.log(paint.bold(" MCP servers:"));
|
|
176154
176682
|
await handleMcp(arg);
|
|
176155
176683
|
console.log();
|
|
@@ -176588,7 +177116,43 @@ ${text}
|
|
|
176588
177116
|
return;
|
|
176589
177117
|
}
|
|
176590
177118
|
default: {
|
|
177119
|
+
const bare = cmd.slice(1);
|
|
177120
|
+
if (bare.startsWith("mcp__") || bare.includes(":"))
|
|
177121
|
+
await mcpReady();
|
|
176591
177122
|
const custom = (0, import_code_core18.findSkill)(skills, cmd);
|
|
177123
|
+
const mcpRef = custom && !bare.startsWith("mcp__") ? null : parseMcpPromptRef(bare, _mcpManager?.serverNames ?? []);
|
|
177124
|
+
if (mcpRef && _mcpManager) {
|
|
177125
|
+
let promptText;
|
|
177126
|
+
try {
|
|
177127
|
+
promptText = await _mcpManager.getPrompt(mcpRef.server, mcpRef.name, splitPromptArgs(arg));
|
|
177128
|
+
} catch (err) {
|
|
177129
|
+
console.log(paint.red(` ${err.message}`));
|
|
177130
|
+
rl.prompt();
|
|
177131
|
+
return;
|
|
177132
|
+
}
|
|
177133
|
+
console.log(paint.dim(` Running /${cmd} (MCP prompt from ${mcpRef.server})...`));
|
|
177134
|
+
checkpoints.beginTurn(`/${cmd} ${arg}`.trim(), messages.length);
|
|
177135
|
+
messages.push({ role: "user", content: [{ type: "text", text: promptText }] });
|
|
177136
|
+
rl.pause();
|
|
177137
|
+
abortSignal.aborted = false;
|
|
177138
|
+
agentRunning = true;
|
|
177139
|
+
try {
|
|
177140
|
+
const result = await runTurn(messages, modelAlias, workDir, abortSignal, env4, nexrallMd, agentMode, effortLevel, checkpoints, saveProgress, takePendingInput, worktreeState, peerCtx);
|
|
177141
|
+
messages = result.messages;
|
|
177142
|
+
updateTitle();
|
|
177143
|
+
saveSession2(sessionId, sessionTitle, workDir, messages);
|
|
177144
|
+
} catch (err) {
|
|
177145
|
+
messages = recoverTurn(err, messages);
|
|
177146
|
+
updateTitle();
|
|
177147
|
+
saveSession2(sessionId, sessionTitle || "Untitled", workDir, messages);
|
|
177148
|
+
} finally {
|
|
177149
|
+
agentRunning = false;
|
|
177150
|
+
commitCheckpoint();
|
|
177151
|
+
}
|
|
177152
|
+
rl.resume();
|
|
177153
|
+
rl.prompt();
|
|
177154
|
+
return;
|
|
177155
|
+
}
|
|
176592
177156
|
if (!custom) {
|
|
176593
177157
|
console.log(paint.red(` Unknown command: ${cmd}`));
|
|
176594
177158
|
console.log(paint.dim(" Type /help for built-ins or /skills for custom ones."));
|