jjhub 0.1.5 → 0.1.7
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/cli/jjhub.mjs +385 -49
- package/package.json +1 -1
package/dist/cli/jjhub.mjs
CHANGED
|
@@ -26536,6 +26536,155 @@ var init_dist = __esm({
|
|
|
26536
26536
|
}
|
|
26537
26537
|
});
|
|
26538
26538
|
|
|
26539
|
+
// node_modules/@modelcontextprotocol/sdk/node_modules/content-type/index.js
|
|
26540
|
+
var require_content_type = __commonJS({
|
|
26541
|
+
"node_modules/@modelcontextprotocol/sdk/node_modules/content-type/index.js"(exports) {
|
|
26542
|
+
"use strict";
|
|
26543
|
+
var PARAM_REGEXP = /; *([!#$%&'*+.^_`|~0-9A-Za-z-]+) *= *("(?:[\u000b\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\u000b\u0020-\u00ff])*"|[!#$%&'*+.^_`|~0-9A-Za-z-]+) */g;
|
|
26544
|
+
var TEXT_REGEXP = /^[\u000b\u0020-\u007e\u0080-\u00ff]+$/;
|
|
26545
|
+
var TOKEN_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
|
|
26546
|
+
var QESC_REGEXP = /\\([\u000b\u0020-\u00ff])/g;
|
|
26547
|
+
var QUOTE_REGEXP = /([\\"])/g;
|
|
26548
|
+
var TYPE_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
|
|
26549
|
+
exports.format = format;
|
|
26550
|
+
exports.parse = parse3;
|
|
26551
|
+
function format(obj) {
|
|
26552
|
+
if (!obj || typeof obj !== "object") {
|
|
26553
|
+
throw new TypeError("argument obj is required");
|
|
26554
|
+
}
|
|
26555
|
+
var parameters = obj.parameters;
|
|
26556
|
+
var type = obj.type;
|
|
26557
|
+
if (!type || !TYPE_REGEXP.test(type)) {
|
|
26558
|
+
throw new TypeError("invalid type");
|
|
26559
|
+
}
|
|
26560
|
+
var string4 = type;
|
|
26561
|
+
if (parameters && typeof parameters === "object") {
|
|
26562
|
+
var param;
|
|
26563
|
+
var params = Object.keys(parameters).sort();
|
|
26564
|
+
for (var i2 = 0; i2 < params.length; i2++) {
|
|
26565
|
+
param = params[i2];
|
|
26566
|
+
if (!TOKEN_REGEXP.test(param)) {
|
|
26567
|
+
throw new TypeError("invalid parameter name");
|
|
26568
|
+
}
|
|
26569
|
+
string4 += "; " + param + "=" + qstring(parameters[param]);
|
|
26570
|
+
}
|
|
26571
|
+
}
|
|
26572
|
+
return string4;
|
|
26573
|
+
}
|
|
26574
|
+
function parse3(string4) {
|
|
26575
|
+
if (!string4) {
|
|
26576
|
+
throw new TypeError("argument string is required");
|
|
26577
|
+
}
|
|
26578
|
+
var header = typeof string4 === "object" ? getcontenttype(string4) : string4;
|
|
26579
|
+
if (typeof header !== "string") {
|
|
26580
|
+
throw new TypeError("argument string is required to be a string");
|
|
26581
|
+
}
|
|
26582
|
+
var index4 = header.indexOf(";");
|
|
26583
|
+
var type = index4 !== -1 ? header.slice(0, index4).trim() : header.trim();
|
|
26584
|
+
if (!TYPE_REGEXP.test(type)) {
|
|
26585
|
+
throw new TypeError("invalid media type");
|
|
26586
|
+
}
|
|
26587
|
+
var obj = new ContentType(type.toLowerCase());
|
|
26588
|
+
if (index4 !== -1) {
|
|
26589
|
+
var key;
|
|
26590
|
+
var match;
|
|
26591
|
+
var value;
|
|
26592
|
+
PARAM_REGEXP.lastIndex = index4;
|
|
26593
|
+
while (match = PARAM_REGEXP.exec(header)) {
|
|
26594
|
+
if (match.index !== index4) {
|
|
26595
|
+
throw new TypeError("invalid parameter format");
|
|
26596
|
+
}
|
|
26597
|
+
index4 += match[0].length;
|
|
26598
|
+
key = match[1].toLowerCase();
|
|
26599
|
+
value = match[2];
|
|
26600
|
+
if (value.charCodeAt(0) === 34) {
|
|
26601
|
+
value = value.slice(1, -1);
|
|
26602
|
+
if (value.indexOf("\\") !== -1) {
|
|
26603
|
+
value = value.replace(QESC_REGEXP, "$1");
|
|
26604
|
+
}
|
|
26605
|
+
}
|
|
26606
|
+
obj.parameters[key] = value;
|
|
26607
|
+
}
|
|
26608
|
+
if (index4 !== header.length) {
|
|
26609
|
+
throw new TypeError("invalid parameter format");
|
|
26610
|
+
}
|
|
26611
|
+
}
|
|
26612
|
+
return obj;
|
|
26613
|
+
}
|
|
26614
|
+
function getcontenttype(obj) {
|
|
26615
|
+
var header;
|
|
26616
|
+
if (typeof obj.getHeader === "function") {
|
|
26617
|
+
header = obj.getHeader("content-type");
|
|
26618
|
+
} else if (typeof obj.headers === "object") {
|
|
26619
|
+
header = obj.headers && obj.headers["content-type"];
|
|
26620
|
+
}
|
|
26621
|
+
if (typeof header !== "string") {
|
|
26622
|
+
throw new TypeError("content-type header is missing from object");
|
|
26623
|
+
}
|
|
26624
|
+
return header;
|
|
26625
|
+
}
|
|
26626
|
+
function qstring(val) {
|
|
26627
|
+
var str = String(val);
|
|
26628
|
+
if (TOKEN_REGEXP.test(str)) {
|
|
26629
|
+
return str;
|
|
26630
|
+
}
|
|
26631
|
+
if (str.length > 0 && !TEXT_REGEXP.test(str)) {
|
|
26632
|
+
throw new TypeError("invalid parameter value");
|
|
26633
|
+
}
|
|
26634
|
+
return '"' + str.replace(QUOTE_REGEXP, "\\$1") + '"';
|
|
26635
|
+
}
|
|
26636
|
+
function ContentType(type) {
|
|
26637
|
+
this.parameters = /* @__PURE__ */ Object.create(null);
|
|
26638
|
+
this.type = type;
|
|
26639
|
+
}
|
|
26640
|
+
}
|
|
26641
|
+
});
|
|
26642
|
+
|
|
26643
|
+
// node_modules/@modelcontextprotocol/sdk/dist/esm/shared/mediaType.js
|
|
26644
|
+
function mediaTypeEssence(header) {
|
|
26645
|
+
if (!header) {
|
|
26646
|
+
return void 0;
|
|
26647
|
+
}
|
|
26648
|
+
try {
|
|
26649
|
+
return import_content_type.default.parse(header).type;
|
|
26650
|
+
} catch {
|
|
26651
|
+
const essence = (header.split(";", 1)[0] ?? "").trim().toLowerCase();
|
|
26652
|
+
if (essence === "" || header.slice(essence.length).includes(",")) {
|
|
26653
|
+
return void 0;
|
|
26654
|
+
}
|
|
26655
|
+
return essence;
|
|
26656
|
+
}
|
|
26657
|
+
}
|
|
26658
|
+
function isJsonContentType(header) {
|
|
26659
|
+
if (header === "application/json") {
|
|
26660
|
+
return true;
|
|
26661
|
+
}
|
|
26662
|
+
return mediaTypeEssence(header) === "application/json";
|
|
26663
|
+
}
|
|
26664
|
+
var import_content_type;
|
|
26665
|
+
var init_mediaType = __esm({
|
|
26666
|
+
"node_modules/@modelcontextprotocol/sdk/dist/esm/shared/mediaType.js"() {
|
|
26667
|
+
import_content_type = __toESM(require_content_type(), 1);
|
|
26668
|
+
}
|
|
26669
|
+
});
|
|
26670
|
+
|
|
26671
|
+
// node_modules/@modelcontextprotocol/sdk/dist/esm/server/sseKeepAlive.js
|
|
26672
|
+
function armSseKeepAlive(intervalMs, onTick) {
|
|
26673
|
+
if (!Number.isFinite(intervalMs) || intervalMs < 1) {
|
|
26674
|
+
return void 0;
|
|
26675
|
+
}
|
|
26676
|
+
const timer = setInterval(onTick, Math.min(intervalMs, MAX_TIMER_DELAY_MS));
|
|
26677
|
+
timer.unref?.();
|
|
26678
|
+
return timer;
|
|
26679
|
+
}
|
|
26680
|
+
var DEFAULT_SSE_KEEP_ALIVE_MS, MAX_TIMER_DELAY_MS;
|
|
26681
|
+
var init_sseKeepAlive = __esm({
|
|
26682
|
+
"node_modules/@modelcontextprotocol/sdk/dist/esm/server/sseKeepAlive.js"() {
|
|
26683
|
+
DEFAULT_SSE_KEEP_ALIVE_MS = 15e3;
|
|
26684
|
+
MAX_TIMER_DELAY_MS = 2 ** 31 - 1;
|
|
26685
|
+
}
|
|
26686
|
+
});
|
|
26687
|
+
|
|
26539
26688
|
// node_modules/zod/v4/core/core.js
|
|
26540
26689
|
// @__NO_SIDE_EFFECTS__
|
|
26541
26690
|
function $constructor(name, initializer3, params) {
|
|
@@ -43166,6 +43315,8 @@ var init_types = __esm({
|
|
|
43166
43315
|
var WebStandardStreamableHTTPServerTransport;
|
|
43167
43316
|
var init_webStandardStreamableHttp = __esm({
|
|
43168
43317
|
"node_modules/@modelcontextprotocol/sdk/dist/esm/server/webStandardStreamableHttp.js"() {
|
|
43318
|
+
init_mediaType();
|
|
43319
|
+
init_sseKeepAlive();
|
|
43169
43320
|
init_types();
|
|
43170
43321
|
WebStandardStreamableHTTPServerTransport = class {
|
|
43171
43322
|
constructor(options = {}) {
|
|
@@ -43173,10 +43324,12 @@ var init_webStandardStreamableHttp = __esm({
|
|
|
43173
43324
|
this._hasHandledRequest = false;
|
|
43174
43325
|
this._streamMapping = /* @__PURE__ */ new Map();
|
|
43175
43326
|
this._requestToStreamMapping = /* @__PURE__ */ new Map();
|
|
43327
|
+
this._resumableStreams = /* @__PURE__ */ new Set();
|
|
43176
43328
|
this._requestResponseMap = /* @__PURE__ */ new Map();
|
|
43177
43329
|
this._initialized = false;
|
|
43178
43330
|
this._enableJsonResponse = false;
|
|
43179
43331
|
this._standaloneSseStreamId = "_GET_stream";
|
|
43332
|
+
this._closed = false;
|
|
43180
43333
|
this.sessionIdGenerator = options.sessionIdGenerator;
|
|
43181
43334
|
this._enableJsonResponse = options.enableJsonResponse ?? false;
|
|
43182
43335
|
this._eventStore = options.eventStore;
|
|
@@ -43186,6 +43339,27 @@ var init_webStandardStreamableHttp = __esm({
|
|
|
43186
43339
|
this._allowedOrigins = options.allowedOrigins;
|
|
43187
43340
|
this._enableDnsRebindingProtection = options.enableDnsRebindingProtection ?? false;
|
|
43188
43341
|
this._retryInterval = options.retryInterval;
|
|
43342
|
+
this._keepAliveMs = options.keepAliveMs ?? DEFAULT_SSE_KEEP_ALIVE_MS;
|
|
43343
|
+
}
|
|
43344
|
+
/**
|
|
43345
|
+
* Arms a keep-alive interval for an SSE stream that periodically writes an SSE
|
|
43346
|
+
* comment frame so intermediaries and idle timeouts don't kill the connection.
|
|
43347
|
+
* The returned timer is owned by the stream it was armed for: the stream's
|
|
43348
|
+
* cancel/cleanup callbacks must clear it. The interval clears itself if a
|
|
43349
|
+
* write fails (stream already closed/cancelled).
|
|
43350
|
+
*/
|
|
43351
|
+
startKeepAlive(controller, encoder) {
|
|
43352
|
+
if (this._closed)
|
|
43353
|
+
return void 0;
|
|
43354
|
+
const timer = armSseKeepAlive(this._keepAliveMs, () => {
|
|
43355
|
+
try {
|
|
43356
|
+
controller.enqueue(encoder.encode(": keepalive\n\n"));
|
|
43357
|
+
} catch {
|
|
43358
|
+
if (timer !== void 0)
|
|
43359
|
+
clearInterval(timer);
|
|
43360
|
+
}
|
|
43361
|
+
});
|
|
43362
|
+
return timer;
|
|
43189
43363
|
}
|
|
43190
43364
|
/**
|
|
43191
43365
|
* Starts the transport. This is required by the Transport interface but is a no-op
|
|
@@ -43248,6 +43422,9 @@ var init_webStandardStreamableHttp = __esm({
|
|
|
43248
43422
|
* Returns a Response object (Web Standard)
|
|
43249
43423
|
*/
|
|
43250
43424
|
async handleRequest(req, options) {
|
|
43425
|
+
if (this._closed) {
|
|
43426
|
+
return this.createJsonErrorResponse(404, -32001, "Session not found");
|
|
43427
|
+
}
|
|
43251
43428
|
if (!this.sessionIdGenerator && this._hasHandledRequest) {
|
|
43252
43429
|
throw new Error("Stateless transport cannot be reused across requests. Create a new transport per request.");
|
|
43253
43430
|
}
|
|
@@ -43292,6 +43469,7 @@ data:
|
|
|
43292
43469
|
`;
|
|
43293
43470
|
}
|
|
43294
43471
|
controller.enqueue(encoder.encode(primingEvent));
|
|
43472
|
+
this._resumableStreams.add(streamId);
|
|
43295
43473
|
}
|
|
43296
43474
|
/**
|
|
43297
43475
|
* Handles GET requests for SSE stream
|
|
@@ -43322,18 +43500,25 @@ data:
|
|
|
43322
43500
|
}
|
|
43323
43501
|
const encoder = new TextEncoder();
|
|
43324
43502
|
let streamController;
|
|
43503
|
+
let keepAliveTimer = void 0;
|
|
43325
43504
|
const readable = new ReadableStream({
|
|
43326
43505
|
start: (controller) => {
|
|
43327
43506
|
streamController = controller;
|
|
43328
43507
|
},
|
|
43329
43508
|
cancel: () => {
|
|
43330
|
-
|
|
43509
|
+
if (keepAliveTimer !== void 0) {
|
|
43510
|
+
clearInterval(keepAliveTimer);
|
|
43511
|
+
}
|
|
43512
|
+
if (this._streamMapping.get(this._standaloneSseStreamId)?.controller === streamController) {
|
|
43513
|
+
this._streamMapping.delete(this._standaloneSseStreamId);
|
|
43514
|
+
}
|
|
43331
43515
|
}
|
|
43332
43516
|
});
|
|
43333
43517
|
const headers = {
|
|
43334
43518
|
"Content-Type": "text/event-stream",
|
|
43335
43519
|
"Cache-Control": "no-cache, no-transform",
|
|
43336
|
-
Connection: "keep-alive"
|
|
43520
|
+
Connection: "keep-alive",
|
|
43521
|
+
"X-Accel-Buffering": "no"
|
|
43337
43522
|
};
|
|
43338
43523
|
if (this.sessionId !== void 0) {
|
|
43339
43524
|
headers["mcp-session-id"] = this.sessionId;
|
|
@@ -43342,6 +43527,9 @@ data:
|
|
|
43342
43527
|
controller: streamController,
|
|
43343
43528
|
encoder,
|
|
43344
43529
|
cleanup: () => {
|
|
43530
|
+
if (keepAliveTimer !== void 0) {
|
|
43531
|
+
clearInterval(keepAliveTimer);
|
|
43532
|
+
}
|
|
43345
43533
|
this._streamMapping.delete(this._standaloneSseStreamId);
|
|
43346
43534
|
try {
|
|
43347
43535
|
streamController.close();
|
|
@@ -43349,6 +43537,7 @@ data:
|
|
|
43349
43537
|
}
|
|
43350
43538
|
}
|
|
43351
43539
|
});
|
|
43540
|
+
keepAliveTimer = this.startKeepAlive(streamController, encoder);
|
|
43352
43541
|
return new Response(readable, { headers });
|
|
43353
43542
|
}
|
|
43354
43543
|
/**
|
|
@@ -43376,21 +43565,33 @@ data:
|
|
|
43376
43565
|
const headers = {
|
|
43377
43566
|
"Content-Type": "text/event-stream",
|
|
43378
43567
|
"Cache-Control": "no-cache, no-transform",
|
|
43379
|
-
Connection: "keep-alive"
|
|
43568
|
+
Connection: "keep-alive",
|
|
43569
|
+
"X-Accel-Buffering": "no"
|
|
43380
43570
|
};
|
|
43381
43571
|
if (this.sessionId !== void 0) {
|
|
43382
43572
|
headers["mcp-session-id"] = this.sessionId;
|
|
43383
43573
|
}
|
|
43384
43574
|
const encoder = new TextEncoder();
|
|
43385
43575
|
let streamController;
|
|
43576
|
+
let keepAliveTimer = void 0;
|
|
43577
|
+
let replayedStreamId = void 0;
|
|
43578
|
+
let cancelled = false;
|
|
43386
43579
|
const readable = new ReadableStream({
|
|
43387
43580
|
start: (controller) => {
|
|
43388
43581
|
streamController = controller;
|
|
43389
43582
|
},
|
|
43390
43583
|
cancel: () => {
|
|
43584
|
+
cancelled = true;
|
|
43585
|
+
if (keepAliveTimer !== void 0) {
|
|
43586
|
+
clearInterval(keepAliveTimer);
|
|
43587
|
+
}
|
|
43588
|
+
if (replayedStreamId !== void 0 && this._streamMapping.get(replayedStreamId)?.controller === streamController) {
|
|
43589
|
+
this._streamMapping.delete(replayedStreamId);
|
|
43590
|
+
}
|
|
43391
43591
|
}
|
|
43392
43592
|
});
|
|
43393
|
-
const
|
|
43593
|
+
const replayedEventIds = /* @__PURE__ */ new Set();
|
|
43594
|
+
replayedStreamId = await this._eventStore.replayEventsAfter(lastEventId, {
|
|
43394
43595
|
send: async (eventId, message) => {
|
|
43395
43596
|
const success2 = this.writeSSEEvent(streamController, encoder, message, eventId);
|
|
43396
43597
|
if (!success2) {
|
|
@@ -43399,13 +43600,27 @@ data:
|
|
|
43399
43600
|
streamController.close();
|
|
43400
43601
|
} catch {
|
|
43401
43602
|
}
|
|
43603
|
+
} else {
|
|
43604
|
+
replayedEventIds.add(eventId);
|
|
43402
43605
|
}
|
|
43403
43606
|
}
|
|
43404
43607
|
});
|
|
43608
|
+
if (this._closed || cancelled) {
|
|
43609
|
+
try {
|
|
43610
|
+
streamController.close();
|
|
43611
|
+
} catch {
|
|
43612
|
+
}
|
|
43613
|
+
return this.createJsonErrorResponse(404, -32001, "Session not found");
|
|
43614
|
+
}
|
|
43615
|
+
this._streamMapping.get(replayedStreamId)?.cleanup();
|
|
43405
43616
|
this._streamMapping.set(replayedStreamId, {
|
|
43406
43617
|
controller: streamController,
|
|
43407
43618
|
encoder,
|
|
43619
|
+
replayedEventIds,
|
|
43408
43620
|
cleanup: () => {
|
|
43621
|
+
if (keepAliveTimer !== void 0) {
|
|
43622
|
+
clearInterval(keepAliveTimer);
|
|
43623
|
+
}
|
|
43409
43624
|
this._streamMapping.delete(replayedStreamId);
|
|
43410
43625
|
try {
|
|
43411
43626
|
streamController.close();
|
|
@@ -43413,6 +43628,8 @@ data:
|
|
|
43413
43628
|
}
|
|
43414
43629
|
}
|
|
43415
43630
|
});
|
|
43631
|
+
this._resumableStreams.add(replayedStreamId);
|
|
43632
|
+
keepAliveTimer = this.startKeepAlive(streamController, encoder);
|
|
43416
43633
|
return new Response(readable, { headers });
|
|
43417
43634
|
} catch (error51) {
|
|
43418
43635
|
this.onerror?.(error51);
|
|
@@ -43471,7 +43688,7 @@ data:
|
|
|
43471
43688
|
return this.createJsonErrorResponse(406, -32e3, "Not Acceptable: Client must accept both application/json and text/event-stream");
|
|
43472
43689
|
}
|
|
43473
43690
|
const ct = req.headers.get("content-type");
|
|
43474
|
-
if (!ct
|
|
43691
|
+
if (!isJsonContentType(ct)) {
|
|
43475
43692
|
this.onerror?.(new Error("Unsupported Media Type: Content-Type must be application/json"));
|
|
43476
43693
|
return this.createJsonErrorResponse(415, -32e3, "Unsupported Media Type: Content-Type must be application/json");
|
|
43477
43694
|
}
|
|
@@ -43501,6 +43718,9 @@ data:
|
|
|
43501
43718
|
this.onerror?.(new Error("Parse error: Invalid JSON-RPC message"));
|
|
43502
43719
|
return this.createJsonErrorResponse(400, -32700, "Parse error: Invalid JSON-RPC message");
|
|
43503
43720
|
}
|
|
43721
|
+
if (this._closed) {
|
|
43722
|
+
return this.createJsonErrorResponse(404, -32001, "Session not found");
|
|
43723
|
+
}
|
|
43504
43724
|
const isInitializationRequest = messages.some(isInitializeRequest);
|
|
43505
43725
|
if (isInitializationRequest) {
|
|
43506
43726
|
if (this._initialized && this.sessionId !== void 0) {
|
|
@@ -43527,6 +43747,9 @@ data:
|
|
|
43527
43747
|
return protocolError;
|
|
43528
43748
|
}
|
|
43529
43749
|
}
|
|
43750
|
+
if (this._closed) {
|
|
43751
|
+
return this.createJsonErrorResponse(404, -32001, "Session not found");
|
|
43752
|
+
}
|
|
43530
43753
|
const hasRequests = messages.some(isJSONRPCRequest);
|
|
43531
43754
|
if (!hasRequests) {
|
|
43532
43755
|
for (const message of messages) {
|
|
@@ -43557,18 +43780,25 @@ data:
|
|
|
43557
43780
|
}
|
|
43558
43781
|
const encoder = new TextEncoder();
|
|
43559
43782
|
let streamController;
|
|
43783
|
+
let keepAliveTimer = void 0;
|
|
43560
43784
|
const readable = new ReadableStream({
|
|
43561
43785
|
start: (controller) => {
|
|
43562
43786
|
streamController = controller;
|
|
43563
43787
|
},
|
|
43564
43788
|
cancel: () => {
|
|
43565
|
-
|
|
43789
|
+
if (keepAliveTimer !== void 0) {
|
|
43790
|
+
clearInterval(keepAliveTimer);
|
|
43791
|
+
}
|
|
43792
|
+
if (this._streamMapping.get(streamId)?.controller === streamController) {
|
|
43793
|
+
this._streamMapping.delete(streamId);
|
|
43794
|
+
}
|
|
43566
43795
|
}
|
|
43567
43796
|
});
|
|
43568
43797
|
const headers = {
|
|
43569
43798
|
"Content-Type": "text/event-stream",
|
|
43570
|
-
"Cache-Control": "no-cache",
|
|
43571
|
-
Connection: "keep-alive"
|
|
43799
|
+
"Cache-Control": "no-cache, no-transform",
|
|
43800
|
+
Connection: "keep-alive",
|
|
43801
|
+
"X-Accel-Buffering": "no"
|
|
43572
43802
|
};
|
|
43573
43803
|
if (this.sessionId !== void 0) {
|
|
43574
43804
|
headers["mcp-session-id"] = this.sessionId;
|
|
@@ -43579,6 +43809,9 @@ data:
|
|
|
43579
43809
|
controller: streamController,
|
|
43580
43810
|
encoder,
|
|
43581
43811
|
cleanup: () => {
|
|
43812
|
+
if (keepAliveTimer !== void 0) {
|
|
43813
|
+
clearInterval(keepAliveTimer);
|
|
43814
|
+
}
|
|
43582
43815
|
this._streamMapping.delete(streamId);
|
|
43583
43816
|
try {
|
|
43584
43817
|
streamController.close();
|
|
@@ -43589,19 +43822,33 @@ data:
|
|
|
43589
43822
|
this._requestToStreamMapping.set(message.id, streamId);
|
|
43590
43823
|
}
|
|
43591
43824
|
}
|
|
43592
|
-
|
|
43593
|
-
|
|
43594
|
-
|
|
43595
|
-
|
|
43596
|
-
|
|
43597
|
-
|
|
43598
|
-
|
|
43599
|
-
|
|
43600
|
-
|
|
43601
|
-
|
|
43602
|
-
|
|
43825
|
+
try {
|
|
43826
|
+
await this.writePrimingEvent(streamController, encoder, streamId, clientProtocolVersion);
|
|
43827
|
+
for (const message of messages) {
|
|
43828
|
+
let closeSSEStream;
|
|
43829
|
+
let closeStandaloneSSEStream;
|
|
43830
|
+
if (isJSONRPCRequest(message) && this._eventStore && clientProtocolVersion >= "2025-11-25") {
|
|
43831
|
+
closeSSEStream = () => {
|
|
43832
|
+
this.closeSSEStream(message.id);
|
|
43833
|
+
};
|
|
43834
|
+
closeStandaloneSSEStream = () => {
|
|
43835
|
+
this.closeStandaloneSSEStream();
|
|
43836
|
+
};
|
|
43837
|
+
}
|
|
43838
|
+
this.onmessage?.(message, { authInfo: options?.authInfo, requestInfo, closeSSEStream, closeStandaloneSSEStream });
|
|
43839
|
+
}
|
|
43840
|
+
} catch (error51) {
|
|
43841
|
+
this._streamMapping.get(streamId)?.cleanup();
|
|
43842
|
+
this._resumableStreams.delete(streamId);
|
|
43843
|
+
for (const message of messages) {
|
|
43844
|
+
if (isJSONRPCRequest(message)) {
|
|
43845
|
+
this._requestToStreamMapping.delete(message.id);
|
|
43846
|
+
}
|
|
43603
43847
|
}
|
|
43604
|
-
|
|
43848
|
+
throw error51;
|
|
43849
|
+
}
|
|
43850
|
+
if (this._streamMapping.get(streamId)?.controller === streamController) {
|
|
43851
|
+
keepAliveTimer = this.startKeepAlive(streamController, encoder);
|
|
43605
43852
|
}
|
|
43606
43853
|
return new Response(readable, { status: 200, headers });
|
|
43607
43854
|
} catch (error51) {
|
|
@@ -43621,9 +43868,12 @@ data:
|
|
|
43621
43868
|
if (protocolError) {
|
|
43622
43869
|
return protocolError;
|
|
43623
43870
|
}
|
|
43624
|
-
|
|
43625
|
-
|
|
43626
|
-
|
|
43871
|
+
try {
|
|
43872
|
+
await Promise.resolve(this._onsessionclosed?.(this.sessionId));
|
|
43873
|
+
return new Response(null, { status: 200 });
|
|
43874
|
+
} finally {
|
|
43875
|
+
await this.close();
|
|
43876
|
+
}
|
|
43627
43877
|
}
|
|
43628
43878
|
/**
|
|
43629
43879
|
* Validates session ID for non-initialization requests.
|
|
@@ -43670,11 +43920,16 @@ data:
|
|
|
43670
43920
|
return void 0;
|
|
43671
43921
|
}
|
|
43672
43922
|
async close() {
|
|
43923
|
+
if (this._closed) {
|
|
43924
|
+
return;
|
|
43925
|
+
}
|
|
43926
|
+
this._closed = true;
|
|
43673
43927
|
this._streamMapping.forEach(({ cleanup: cleanup2 }) => {
|
|
43674
43928
|
cleanup2();
|
|
43675
43929
|
});
|
|
43676
43930
|
this._streamMapping.clear();
|
|
43677
43931
|
this._requestResponseMap.clear();
|
|
43932
|
+
this._resumableStreams.clear();
|
|
43678
43933
|
this.onclose?.();
|
|
43679
43934
|
}
|
|
43680
43935
|
/**
|
|
@@ -43718,7 +43973,7 @@ data:
|
|
|
43718
43973
|
if (standaloneSse === void 0) {
|
|
43719
43974
|
return;
|
|
43720
43975
|
}
|
|
43721
|
-
if (standaloneSse.controller && standaloneSse.encoder) {
|
|
43976
|
+
if (standaloneSse.controller && standaloneSse.encoder && (eventId === void 0 || !standaloneSse.replayedEventIds?.has(eventId))) {
|
|
43722
43977
|
this.writeSSEEvent(standaloneSse.controller, standaloneSse.encoder, message, eventId);
|
|
43723
43978
|
}
|
|
43724
43979
|
return;
|
|
@@ -43727,13 +43982,19 @@ data:
|
|
|
43727
43982
|
if (!streamId) {
|
|
43728
43983
|
throw new Error(`No connection established for request ID: ${String(requestId)}`);
|
|
43729
43984
|
}
|
|
43730
|
-
|
|
43731
|
-
if (!this._enableJsonResponse
|
|
43985
|
+
let stream = this._streamMapping.get(streamId);
|
|
43986
|
+
if (!this._enableJsonResponse) {
|
|
43732
43987
|
let eventId;
|
|
43733
43988
|
if (this._eventStore) {
|
|
43734
43989
|
eventId = await this._eventStore.storeEvent(streamId, message);
|
|
43990
|
+
stream = this._streamMapping.get(streamId);
|
|
43991
|
+
}
|
|
43992
|
+
if (stream?.controller && stream?.encoder && (eventId === void 0 || !stream.replayedEventIds?.has(eventId))) {
|
|
43993
|
+
const written = this.writeSSEEvent(stream.controller, stream.encoder, message, eventId);
|
|
43994
|
+
if (written && eventId !== void 0) {
|
|
43995
|
+
this._resumableStreams.add(streamId);
|
|
43996
|
+
}
|
|
43735
43997
|
}
|
|
43736
|
-
this.writeSSEEvent(stream.controller, stream.encoder, message, eventId);
|
|
43737
43998
|
}
|
|
43738
43999
|
if (isJSONRPCResultResponse(message) || isJSONRPCErrorResponse(message)) {
|
|
43739
44000
|
this._requestResponseMap.set(requestId, message);
|
|
@@ -43741,6 +44002,25 @@ data:
|
|
|
43741
44002
|
const allResponsesReady = relatedIds.every((id) => this._requestResponseMap.has(id));
|
|
43742
44003
|
if (allResponsesReady) {
|
|
43743
44004
|
if (!stream) {
|
|
44005
|
+
if (this._closed) {
|
|
44006
|
+
for (const id of relatedIds) {
|
|
44007
|
+
this._requestResponseMap.delete(id);
|
|
44008
|
+
this._requestToStreamMapping.delete(id);
|
|
44009
|
+
}
|
|
44010
|
+
return;
|
|
44011
|
+
}
|
|
44012
|
+
if (!this._enableJsonResponse && this._eventStore && this._resumableStreams.has(streamId)) {
|
|
44013
|
+
for (const id of relatedIds) {
|
|
44014
|
+
this._requestResponseMap.delete(id);
|
|
44015
|
+
this._requestToStreamMapping.delete(id);
|
|
44016
|
+
}
|
|
44017
|
+
this._resumableStreams.delete(streamId);
|
|
44018
|
+
return;
|
|
44019
|
+
}
|
|
44020
|
+
for (const id of relatedIds) {
|
|
44021
|
+
this._requestResponseMap.delete(id);
|
|
44022
|
+
this._requestToStreamMapping.delete(id);
|
|
44023
|
+
}
|
|
43744
44024
|
throw new Error(`No connection established for request ID: ${String(requestId)}`);
|
|
43745
44025
|
}
|
|
43746
44026
|
if (this._enableJsonResponse && stream.resolveJson) {
|
|
@@ -43763,6 +44043,7 @@ data:
|
|
|
43763
44043
|
this._requestResponseMap.delete(id);
|
|
43764
44044
|
this._requestToStreamMapping.delete(id);
|
|
43765
44045
|
}
|
|
44046
|
+
this._resumableStreams.delete(streamId);
|
|
43766
44047
|
}
|
|
43767
44048
|
}
|
|
43768
44049
|
}
|
|
@@ -48032,17 +48313,33 @@ function normalizeObjectSchema(schema) {
|
|
|
48032
48313
|
}
|
|
48033
48314
|
return void 0;
|
|
48034
48315
|
}
|
|
48316
|
+
function getDotPath(path3) {
|
|
48317
|
+
if (path3.length === 0) {
|
|
48318
|
+
return "object root";
|
|
48319
|
+
}
|
|
48320
|
+
return path3.reduce((acc, seg, index4) => {
|
|
48321
|
+
if (index4 === 0) {
|
|
48322
|
+
return String(seg);
|
|
48323
|
+
}
|
|
48324
|
+
if (typeof seg === "number") {
|
|
48325
|
+
return `${acc}[${seg}]`;
|
|
48326
|
+
}
|
|
48327
|
+
return `${acc}.${seg}`;
|
|
48328
|
+
}, "");
|
|
48329
|
+
}
|
|
48035
48330
|
function getParseErrorMessage(error51) {
|
|
48036
48331
|
if (error51 && typeof error51 === "object") {
|
|
48332
|
+
if ("issues" in error51 && Array.isArray(error51.issues) && error51.issues.length > 0) {
|
|
48333
|
+
return error51.issues.map((i2) => {
|
|
48334
|
+
if (!i2.path?.length) {
|
|
48335
|
+
return i2.message;
|
|
48336
|
+
}
|
|
48337
|
+
return `${i2.message} at ${getDotPath(i2.path)}`;
|
|
48338
|
+
}).join("\n");
|
|
48339
|
+
}
|
|
48037
48340
|
if ("message" in error51 && typeof error51.message === "string") {
|
|
48038
48341
|
return error51.message;
|
|
48039
48342
|
}
|
|
48040
|
-
if ("issues" in error51 && Array.isArray(error51.issues) && error51.issues.length > 0) {
|
|
48041
|
-
const firstIssue = error51.issues[0];
|
|
48042
|
-
if (firstIssue && typeof firstIssue === "object" && "message" in firstIssue) {
|
|
48043
|
-
return String(firstIssue.message);
|
|
48044
|
-
}
|
|
48045
|
-
}
|
|
48046
48343
|
try {
|
|
48047
48344
|
return JSON.stringify(error51);
|
|
48048
48345
|
} catch {
|
|
@@ -54303,7 +54600,12 @@ var require_fast_uri = __commonJS({
|
|
|
54303
54600
|
}
|
|
54304
54601
|
function resolve(baseURI, relativeURI, options) {
|
|
54305
54602
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
54306
|
-
const
|
|
54603
|
+
const { parsed: baseParsed, malformedAuthorityOrPort: baseMalformed } = parseWithStatus(baseURI, schemelessOptions);
|
|
54604
|
+
const { parsed: relativeParsed, malformedAuthorityOrPort: relativeMalformed } = parseWithStatus(relativeURI, schemelessOptions);
|
|
54605
|
+
if (baseMalformed || relativeMalformed) {
|
|
54606
|
+
throw new Error(baseParsed.error || relativeParsed.error || "URI is malformed.");
|
|
54607
|
+
}
|
|
54608
|
+
const resolved = resolveComponent(baseParsed, relativeParsed, schemelessOptions, true);
|
|
54307
54609
|
schemelessOptions.skipEscape = true;
|
|
54308
54610
|
return serialize(resolved, schemelessOptions);
|
|
54309
54611
|
}
|
|
@@ -54428,6 +54730,8 @@ var require_fast_uri = __commonJS({
|
|
|
54428
54730
|
return uriTokens.join("");
|
|
54429
54731
|
}
|
|
54430
54732
|
var URI_PARSE = /^(?:([^#/:?]+):)?(?:\/\/((?:([^#/?@]*)@)?(\[[^#/?\]]+\]|[^#/:?]*)(?::(\d*))?))?([^#?]*)(?:\?([^#]*))?(?:#((?:.|[\n\r])*))?/u;
|
|
54733
|
+
var AUTHORITY_PREFIX = /^(?:[^#/:?]+:)?\/\/([^/?#]*)/;
|
|
54734
|
+
var AUTHORITY_INTRODUCER_REGION = /^(?:[^#/:?]+:)?([/\\\t\n\r]*)/;
|
|
54431
54735
|
function getParseError(parsed, matches) {
|
|
54432
54736
|
if (matches[2] !== void 0 && parsed.path && parsed.path[0] !== "/") {
|
|
54433
54737
|
return 'URI path must start with "/" when authority is present.';
|
|
@@ -54457,6 +54761,25 @@ var require_fast_uri = __commonJS({
|
|
|
54457
54761
|
uri = "//" + uri;
|
|
54458
54762
|
}
|
|
54459
54763
|
}
|
|
54764
|
+
const authorityMatch = uri.match(AUTHORITY_PREFIX);
|
|
54765
|
+
if (authorityMatch !== null && authorityMatch[1].indexOf("\\") !== -1) {
|
|
54766
|
+
parsed.error = "URI authority must not contain a literal backslash.";
|
|
54767
|
+
malformedAuthorityOrPort = true;
|
|
54768
|
+
}
|
|
54769
|
+
const introducerMatch = uri.match(AUTHORITY_INTRODUCER_REGION);
|
|
54770
|
+
if (introducerMatch !== null) {
|
|
54771
|
+
const region = introducerMatch[1];
|
|
54772
|
+
const normalizedRegion = region.replace(/[\t\n\r]/g, "");
|
|
54773
|
+
if (normalizedRegion.length >= 2) {
|
|
54774
|
+
if (normalizedRegion.slice(0, 2) !== "//") {
|
|
54775
|
+
parsed.error = parsed.error || "URI authority must not contain a literal backslash.";
|
|
54776
|
+
malformedAuthorityOrPort = true;
|
|
54777
|
+
} else if (region.length !== normalizedRegion.length) {
|
|
54778
|
+
parsed.error = parsed.error || "URI authority introducer must not contain whitespace.";
|
|
54779
|
+
malformedAuthorityOrPort = true;
|
|
54780
|
+
}
|
|
54781
|
+
}
|
|
54782
|
+
}
|
|
54460
54783
|
const matches = uri.match(URI_PARSE);
|
|
54461
54784
|
if (matches) {
|
|
54462
54785
|
parsed.scheme = matches[1];
|
|
@@ -57954,16 +58277,7 @@ var init_server2 = __esm({
|
|
|
57954
58277
|
if (!methodSchema) {
|
|
57955
58278
|
throw new Error("Schema is missing a method literal");
|
|
57956
58279
|
}
|
|
57957
|
-
|
|
57958
|
-
if (isZ4Schema(methodSchema)) {
|
|
57959
|
-
const v4Schema = methodSchema;
|
|
57960
|
-
const v4Def = v4Schema._zod?.def;
|
|
57961
|
-
methodValue = v4Def?.value ?? v4Schema.value;
|
|
57962
|
-
} else {
|
|
57963
|
-
const v3Schema = methodSchema;
|
|
57964
|
-
const legacyDef = v3Schema._def;
|
|
57965
|
-
methodValue = legacyDef?.value ?? v3Schema.value;
|
|
57966
|
-
}
|
|
58280
|
+
const methodValue = getLiteralValue(methodSchema);
|
|
57967
58281
|
if (typeof methodValue !== "string") {
|
|
57968
58282
|
throw new Error("Schema method literal must be a string");
|
|
57969
58283
|
}
|
|
@@ -59425,12 +59739,21 @@ function deserializeMessage(line) {
|
|
|
59425
59739
|
function serializeMessage(message) {
|
|
59426
59740
|
return JSON.stringify(message) + "\n";
|
|
59427
59741
|
}
|
|
59428
|
-
var ReadBuffer;
|
|
59742
|
+
var STDIO_DEFAULT_MAX_BUFFER_SIZE, ReadBuffer;
|
|
59429
59743
|
var init_stdio = __esm({
|
|
59430
59744
|
"node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js"() {
|
|
59431
59745
|
init_types();
|
|
59746
|
+
STDIO_DEFAULT_MAX_BUFFER_SIZE = 10 * 1024 * 1024;
|
|
59432
59747
|
ReadBuffer = class {
|
|
59748
|
+
constructor(options) {
|
|
59749
|
+
this._maxBufferSize = options?.maxBufferSize ?? STDIO_DEFAULT_MAX_BUFFER_SIZE;
|
|
59750
|
+
}
|
|
59433
59751
|
append(chunk) {
|
|
59752
|
+
const newSize = (this._buffer?.length ?? 0) + chunk.length;
|
|
59753
|
+
if (newSize > this._maxBufferSize) {
|
|
59754
|
+
this.clear();
|
|
59755
|
+
throw new Error(`ReadBuffer exceeded maximum size of ${this._maxBufferSize} bytes`);
|
|
59756
|
+
}
|
|
59434
59757
|
this._buffer = this._buffer ? Buffer.concat([this._buffer, chunk]) : chunk;
|
|
59435
59758
|
}
|
|
59436
59759
|
readMessage() {
|
|
@@ -59459,18 +59782,24 @@ var init_stdio2 = __esm({
|
|
|
59459
59782
|
"node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js"() {
|
|
59460
59783
|
init_stdio();
|
|
59461
59784
|
StdioServerTransport = class {
|
|
59462
|
-
constructor(_stdin = process3.stdin, _stdout = process3.stdout) {
|
|
59785
|
+
constructor(_stdin = process3.stdin, _stdout = process3.stdout, options) {
|
|
59463
59786
|
this._stdin = _stdin;
|
|
59464
59787
|
this._stdout = _stdout;
|
|
59465
|
-
this._readBuffer = new ReadBuffer();
|
|
59466
59788
|
this._started = false;
|
|
59467
59789
|
this._ondata = (chunk) => {
|
|
59468
|
-
|
|
59469
|
-
|
|
59790
|
+
try {
|
|
59791
|
+
this._readBuffer.append(chunk);
|
|
59792
|
+
this.processReadBuffer();
|
|
59793
|
+
} catch (error51) {
|
|
59794
|
+
this.onerror?.(error51);
|
|
59795
|
+
this.close().catch(() => {
|
|
59796
|
+
});
|
|
59797
|
+
}
|
|
59470
59798
|
};
|
|
59471
59799
|
this._onerror = (error51) => {
|
|
59472
59800
|
this.onerror?.(error51);
|
|
59473
59801
|
};
|
|
59802
|
+
this._readBuffer = new ReadBuffer({ maxBufferSize: options?.maxBufferSize });
|
|
59474
59803
|
}
|
|
59475
59804
|
/**
|
|
59476
59805
|
* Starts listening for messages on stdin.
|
|
@@ -120155,6 +120484,13 @@ simple-concat/index.js:
|
|
|
120155
120484
|
simple-get/index.js:
|
|
120156
120485
|
(*! simple-get. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> *)
|
|
120157
120486
|
|
|
120487
|
+
content-type/index.js:
|
|
120488
|
+
(*!
|
|
120489
|
+
* content-type
|
|
120490
|
+
* Copyright(c) 2015 Douglas Christopher Wilson
|
|
120491
|
+
* MIT Licensed
|
|
120492
|
+
*)
|
|
120493
|
+
|
|
120158
120494
|
long/umd/index.js:
|
|
120159
120495
|
(**
|
|
120160
120496
|
* @license
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jjhub",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "jjhub — GitHub CLI with Jujutsu-native superpowers: stable change IDs, stacks, platform-wide undo, and conflicts that wait, layered over plain GitHub repos by a JJHub server.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"jjhub": "./dist/cli/jjhub.mjs"
|