@caplets/core 0.17.0 → 0.18.1

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 CHANGED
@@ -1,15 +1,16 @@
1
- import { A as CompleteRequestSchema, At as string, B as InitializedNotificationSchema, C as assertToolsCallTaskCapability, Ct as resolveProjectConfigPath, D as toJsonSchemaCompat, Dt as ZodOptional, E as mergeCapabilities, Et as SERVER_ID_PATTERN, F as ElicitResultSchema, Ft as toSafeError, G as ListResourcesRequestSchema, H as LATEST_PROTOCOL_VERSION, I as EmptyResultSchema, It as __commonJSMin, J as LoggingLevelSchema, K as ListRootsResultSchema, L as ErrorCode, Lt as __require, M as CreateMessageResultWithToolsSchema, Mt as CAPLETS_ERROR_CODES, N as CreateTaskResultSchema, Nt as CapletsError, O as CallToolRequestSchema, Ot as literal, Pt as redactSecrets, Q as SetLevelRequestSchema, R as GetPromptRequestSchema, Rt as __toESM, S as assertClientRequestTaskCapability, St as resolveProjectCapletsRoot, T as Protocol, Tt as validateCapletFile, U as ListPromptsRequestSchema, V as JSONRPCMessageSchema, W as ListResourceTemplatesRequestSchema, X as ReadResourceRequestSchema, Y as McpError, Z as SUPPORTED_PROTOCOL_VERSIONS, _ as readTokenBundle, _t as loadConfigWithSources, a as resolveCapletsServer, at as isJSONRPCResultResponse, b as serializeMessage, bt as resolveCapletsRoot, c as handleServerTool, ct as getParseErrorMessage, d as runGenericOAuthFlow, dt as isZ4Schema, et as assertCompleteRequestPrompt, f as runOAuthFlow, ft as normalizeObjectSchema, g as isTokenBundleExpired, gt as loadConfig, h as deleteTokenBundle, ht as safeParseAsync, i as resolveCapletsMode, it as isJSONRPCRequest, j as CreateMessageResultSchema, jt as url, k as CallToolResultSchema, kt as object, l as ServerRegistry, lt as getSchemaDescription, m as startOAuthFlow, mt as safeParse, nt as isInitializeRequest, o as CapletsEngine, ot as getLiteralValue, p as startGenericOAuthFlow, pt as objectFromShape, q as ListToolsRequestSchema, r as parseServerBaseUrl, rt as isJSONRPCErrorResponse, s as generatedToolInputSchema, st as getObjectShape, t as controlUrlForBase, tt as assertCompleteRequestResourceTemplate, u as capabilityDescription, ut as isSchemaOptional, vt as parseConfig, w as AjvJsonSchemaValidator, wt as discoverCapletFiles, xt as resolveConfigPath, y as ReadBuffer, yt as DEFAULT_AUTH_DIR, z as InitializeRequestSchema } from "./options-CJEOqS87.js";
1
+ import { $ as assertCompleteRequestPrompt, A as CreateMessageResultSchema, At as toSafeError, B as JSONRPCMessageSchema, C as AjvJsonSchemaValidator, D as CallToolRequestSchema, Dt as CAPLETS_ERROR_CODES, E as toJsonSchemaCompat, Et as SERVER_ID_PATTERN, F as EmptyResultSchema, G as ListRootsResultSchema, H as ListPromptsRequestSchema, I as ErrorCode, J as McpError, K as ListToolsRequestSchema, L as GetPromptRequestSchema, M as CreateTaskResultSchema, Nt as __require, O as CallToolResultSchema, Ot as CapletsError, P as ElicitResultSchema, Pt as __toESM, R as InitializeRequestSchema, S as assertToolsCallTaskCapability, St as resolveProjectCapletsRoot, T as mergeCapabilities, Tt as validateCapletFile, U as ListResourceTemplatesRequestSchema, V as LATEST_PROTOCOL_VERSION, W as ListResourcesRequestSchema, X as SUPPORTED_PROTOCOL_VERSIONS, Y as ReadResourceRequestSchema, Z as SetLevelRequestSchema, _t as parseConfig, a as resolveCapletsServer, at as getLiteralValue, bt as resolveCapletsRoot, c as ServerRegistry, ct as getSchemaDescription, d as runOAuthFlow, dt as normalizeObjectSchema, et as assertCompleteRequestResourceTemplate, f as startGenericOAuthFlow, ft as objectFromShape, g as readTokenBundle, gt as loadConfigWithSources, h as isTokenBundleExpired, ht as loadConfig, i as resolveCapletsMode, it as isJSONRPCResultResponse, j as CreateMessageResultWithToolsSchema, jt as __commonJSMin, k as CompleteRequestSchema, kt as redactSecrets, l as capabilityDescription, lt as isSchemaOptional, m as deleteTokenBundle, mt as safeParseAsync, nt as isJSONRPCErrorResponse, o as CapletsEngine, ot as getObjectShape, p as startOAuthFlow, pt as safeParse, q as LoggingLevelSchema, r as parseServerBaseUrl, rt as isJSONRPCRequest, s as handleServerTool, st as getParseErrorMessage, t as controlUrlForBase, tt as isInitializeRequest, u as runGenericOAuthFlow, ut as isZ4Schema, v as ReadBuffer, w as Protocol, wt as discoverCapletFiles, x as assertClientRequestTaskCapability, xt as resolveConfigPath, y as serializeMessage, z as InitializedNotificationSchema } from "./options-BqibJVxq.js";
2
+ import { A as url, C as object, D as string, b as literal, d as ZodOptional, o as generatedToolInputSchema, s as generatedToolInputSchemaForCaplet } from "./generated-tool-input-schema-BYoyY-l-.js";
3
+ import { a as formatCapletList, c as resolveCliConfigPaths, l as cliCommands, n as completionScript, o as formatConfigPaths, s as listCaplets, t as completeCliWords, u as completionShells } from "./completion-dbB1hc97.js";
2
4
  import { accessSync, chmodSync, closeSync, constants, cpSync, existsSync, lstatSync, mkdirSync, mkdtempSync, openSync, readFileSync, rmSync, statSync, writeFileSync, writeSync } from "node:fs";
3
5
  import { basename, dirname, join, parse, relative, resolve } from "node:path";
4
6
  import { execFileSync } from "node:child_process";
5
7
  import process$1, { stdin, stdout } from "node:process";
6
8
  import { tmpdir } from "node:os";
9
+ import { Readable } from "node:stream";
10
+ import { STATUS_CODES, createServer } from "node:http";
7
11
  import { randomUUID, timingSafeEqual } from "node:crypto";
8
12
  import { createInterface } from "node:readline/promises";
9
- import { createServer } from "http";
10
- import { Http2ServerRequest, constants as constants$1 } from "http2";
11
- import { Readable } from "stream";
12
- import crypto$1 from "crypto";
13
+ import { Http2ServerRequest, constants as constants$1 } from "node:http2";
13
14
  //#region ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.4.3/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/server.js
14
15
  /**
15
16
  * Experimental server task features for MCP SDK.
@@ -1319,7 +1320,7 @@ const EMPTY_COMPLETION_RESULT = { completion: {
1319
1320
  } };
1320
1321
  //#endregion
1321
1322
  //#region package.json
1322
- var version = "0.17.0";
1323
+ var version = "0.18.1";
1323
1324
  //#endregion
1324
1325
  //#region src/serve/session.ts
1325
1326
  var CapletsMcpSession = class {
@@ -1363,6 +1364,7 @@ var CapletsMcpSession = class {
1363
1364
  if (!previousCaplet || serializeCaplet(previousCaplet) !== serializeCaplet(caplet)) tool.update({
1364
1365
  title: caplet.name,
1365
1366
  description: capabilityDescription(caplet),
1367
+ paramsSchema: generatedToolInputSchemaForCaplet(caplet).shape,
1366
1368
  callback: async (request) => this.handleTool(serverId, request),
1367
1369
  enabled: true
1368
1370
  });
@@ -1376,7 +1378,7 @@ var CapletsMcpSession = class {
1376
1378
  return this.server.registerTool(caplet.server, {
1377
1379
  title: caplet.name,
1378
1380
  description: capabilityDescription(caplet),
1379
- inputSchema: generatedToolInputSchema
1381
+ inputSchema: generatedToolInputSchemaForCaplet(caplet).shape
1380
1382
  }, async (request) => this.handleTool(caplet.server, request));
1381
1383
  }
1382
1384
  async handleTool(serverId, request) {
@@ -5042,126 +5044,6 @@ function starterConfig() {
5042
5044
  }, null, 2);
5043
5045
  }
5044
5046
  //#endregion
5045
- //#region src/cli/inspection.ts
5046
- function listCaplets(configWithSources, options) {
5047
- const { config, sources, shadows } = configWithSources;
5048
- return allCaplets(config).filter((server) => options.includeDisabled || !server.disabled).map((server) => ({
5049
- server: server.server,
5050
- backend: server.backend,
5051
- name: server.name,
5052
- description: server.description,
5053
- disabled: server.disabled,
5054
- status: initialServerStatus(server),
5055
- source: sources[server.server]?.kind ?? "unknown",
5056
- path: sources[server.server]?.path ?? null,
5057
- shadows: shadows[server.server] ?? []
5058
- })).sort((left, right) => left.server.localeCompare(right.server));
5059
- }
5060
- function initialServerStatus(server) {
5061
- return server.disabled ? "disabled" : "not_started";
5062
- }
5063
- function allCaplets(config) {
5064
- return [
5065
- ...Object.values(config.mcpServers),
5066
- ...Object.values(config.openapiEndpoints),
5067
- ...Object.values(config.graphqlEndpoints),
5068
- ...Object.values(config.httpApis),
5069
- ...Object.values(config.cliTools)
5070
- ];
5071
- }
5072
- function formatCapletList(rows, format = "plain") {
5073
- return format === "markdown" ? formatCapletListMarkdown(rows) : formatCapletListPlain(rows);
5074
- }
5075
- function formatCapletListMarkdown(rows) {
5076
- if (rows.length === 0) return "## Configured Caplets\n\nNo configured Caplets found.\n";
5077
- const heading = [
5078
- "## Configured Caplets",
5079
- "",
5080
- `${rows.length} ${rows.length === 1 ? "Caplet" : "Caplets"} shown.`,
5081
- ""
5082
- ];
5083
- const entries = rows.flatMap((row) => [
5084
- `- \`${row.server}\` — ${row.name}`,
5085
- ` - Backend: ${row.backend}`,
5086
- ` - Status: ${row.status}`,
5087
- ` - Source: ${row.source}`,
5088
- ...row.disabled ? [" - Disabled: true"] : [],
5089
- ...row.path ? [` - Path: ${row.path}`] : []
5090
- ]);
5091
- const warnings = rows.flatMap((row) => row.shadows.map((shadow) => `Warning: ${formatSourceKind(row.source)} Caplet ${row.server} shadows ${formatSourceKind(shadow.kind)} Caplet at ${shadow.path}`));
5092
- if (warnings.length === 0) return `${[...heading, ...entries].join("\n")}\n`;
5093
- return `${[
5094
- ...heading,
5095
- ...entries,
5096
- "",
5097
- "Warnings:",
5098
- ...warnings.map((warning) => `- ${warning}`)
5099
- ].join("\n")}\n`;
5100
- }
5101
- function formatCapletListPlain(rows) {
5102
- if (rows.length === 0) return "No configured Caplets found.\n";
5103
- const entries = rows.map((row) => [
5104
- row.server,
5105
- ` Name: ${row.name}`,
5106
- ` Backend: ${row.backend}`,
5107
- ` Status: ${row.status}`,
5108
- ` Source: ${row.source}`,
5109
- ...row.disabled ? [" Disabled: true"] : [],
5110
- ...row.path ? [` Path: ${row.path}`] : []
5111
- ].join("\n")).join("\n\n");
5112
- const warnings = rows.flatMap((row) => row.shadows.map((shadow) => `Warning: ${formatSourceKind(row.source)} Caplet ${row.server} shadows ${formatSourceKind(shadow.kind)} Caplet at ${shadow.path}`));
5113
- if (warnings.length === 0) return `Configured Caplets (${rows.length})\n\n${entries}\n`;
5114
- return `Configured Caplets (${rows.length})\n\n${entries}\n\n${warnings.join("\n")}\n`;
5115
- }
5116
- function formatSourceKind(kind) {
5117
- if (kind.startsWith("project")) return "project";
5118
- if (kind.startsWith("global")) return "global";
5119
- return kind;
5120
- }
5121
- function resolveCliConfigPaths(envConfigPath, authDir) {
5122
- const configPath = resolveConfigPath(envConfigPath);
5123
- const effectiveAuthDir = authDir ?? DEFAULT_AUTH_DIR;
5124
- return {
5125
- userConfig: configPath,
5126
- projectConfig: resolveProjectConfigPath(),
5127
- userRoot: resolveCapletsRoot(configPath),
5128
- stateRoot: dirname(effectiveAuthDir),
5129
- projectRoot: resolveProjectCapletsRoot(),
5130
- authDir: effectiveAuthDir,
5131
- envConfig: envConfigPath ?? null
5132
- };
5133
- }
5134
- function formatConfigPaths(paths, format = "plain") {
5135
- if (format === "markdown") return formatConfigPathsMarkdown(paths);
5136
- return formatConfigPathsPlain(paths);
5137
- }
5138
- function formatConfigPathsMarkdown(paths) {
5139
- return [
5140
- "## Caplets paths",
5141
- "",
5142
- `- User config: ${paths.userConfig}`,
5143
- `- Project config: ${paths.projectConfig}`,
5144
- `- User Caplets root: ${paths.userRoot}`,
5145
- `- State root: ${paths.stateRoot}`,
5146
- `- Project Caplets root: ${paths.projectRoot}`,
5147
- `- Auth directory: ${paths.authDir}`,
5148
- `- CAPLETS_CONFIG: ${paths.envConfig ?? "unset"}`
5149
- ].join("\n") + "\n";
5150
- }
5151
- function formatConfigPathsPlain(paths) {
5152
- return [
5153
- "Caplets paths",
5154
- "",
5155
- `User config: ${paths.userConfig}`,
5156
- `Project config: ${paths.projectConfig}`,
5157
- `User root: ${paths.userRoot}`,
5158
- `State root: ${paths.stateRoot}`,
5159
- `Project root: ${paths.projectRoot}`,
5160
- `Auth directory: ${paths.authDir}`,
5161
- `CAPLETS_CONFIG: ${paths.envConfig ?? "unset"}`
5162
- ].join("\n") + "\n";
5163
- }
5164
- //#endregion
5165
5047
  //#region src/cli/install.ts
5166
5048
  function installCaplets(repo, options = {}) {
5167
5049
  const source = resolveInstallSource(repo);
@@ -5487,7 +5369,7 @@ function redactRemoteMessage(message) {
5487
5369
  return String(redactSecrets(message)).replace(/\b(authorization\s*:\s*(?:basic|bearer)\s+)[^\s,;]+/giu, "$1[REDACTED]").replace(/\b((?:access_)?token=)[^\s,;]+/giu, "$1[REDACTED]").replace(/\b((?:token|secret|authorization|auth|api[-_]?key|password|credential|clientsecret|client_secret|code|refresh(?:_token)?)\s*[=:]\s*)[^\s,;]+/giu, "$1[REDACTED]");
5488
5370
  }
5489
5371
  //#endregion
5490
- //#region ../../node_modules/.pnpm/hono@4.12.19/node_modules/hono/dist/compose.js
5372
+ //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/compose.js
5491
5373
  var compose = (middleware, onError, onNotFound) => {
5492
5374
  return (context, next) => {
5493
5375
  let index = -1;
@@ -5518,7 +5400,7 @@ var compose = (middleware, onError, onNotFound) => {
5518
5400
  };
5519
5401
  };
5520
5402
  //#endregion
5521
- //#region ../../node_modules/.pnpm/hono@4.12.19/node_modules/hono/dist/http-exception.js
5403
+ //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/http-exception.js
5522
5404
  var HTTPException = class extends Error {
5523
5405
  res;
5524
5406
  status;
@@ -5546,10 +5428,10 @@ var HTTPException = class extends Error {
5546
5428
  }
5547
5429
  };
5548
5430
  //#endregion
5549
- //#region ../../node_modules/.pnpm/hono@4.12.19/node_modules/hono/dist/request/constants.js
5431
+ //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/request/constants.js
5550
5432
  var GET_MATCH_RESULT = /* @__PURE__ */ Symbol();
5551
5433
  //#endregion
5552
- //#region ../../node_modules/.pnpm/hono@4.12.19/node_modules/hono/dist/utils/body.js
5434
+ //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/utils/body.js
5553
5435
  var parseBody = async (request, options = /* @__PURE__ */ Object.create(null)) => {
5554
5436
  const { all = false, dot = false } = options;
5555
5437
  const contentType = (request instanceof HonoRequest ? request.raw.headers : request.headers).get("Content-Type");
@@ -5597,7 +5479,7 @@ var handleParsingNestedValues = (form, key, value) => {
5597
5479
  });
5598
5480
  };
5599
5481
  //#endregion
5600
- //#region ../../node_modules/.pnpm/hono@4.12.19/node_modules/hono/dist/utils/url.js
5482
+ //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/utils/url.js
5601
5483
  var splitPath = (path) => {
5602
5484
  const paths = path.split("/");
5603
5485
  if (paths[0] === "") paths.shift();
@@ -5761,7 +5643,7 @@ var getQueryParams = (url, key) => {
5761
5643
  };
5762
5644
  var decodeURIComponent_ = decodeURIComponent;
5763
5645
  //#endregion
5764
- //#region ../../node_modules/.pnpm/hono@4.12.19/node_modules/hono/dist/request.js
5646
+ //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/request.js
5765
5647
  var tryDecodeURIComponent = (str) => tryDecode(str, decodeURIComponent_);
5766
5648
  var HonoRequest = class {
5767
5649
  /**
@@ -6033,7 +5915,7 @@ var HonoRequest = class {
6033
5915
  }
6034
5916
  };
6035
5917
  //#endregion
6036
- //#region ../../node_modules/.pnpm/hono@4.12.19/node_modules/hono/dist/utils/html.js
5918
+ //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/utils/html.js
6037
5919
  var HtmlEscapedCallbackPhase = {
6038
5920
  Stringify: 1,
6039
5921
  BeforeStream: 2,
@@ -6063,7 +5945,7 @@ var resolveCallback = async (str, phase, preserveCallbacks, context, buffer) =>
6063
5945
  else return resStr;
6064
5946
  };
6065
5947
  //#endregion
6066
- //#region ../../node_modules/.pnpm/hono@4.12.19/node_modules/hono/dist/context.js
5948
+ //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/context.js
6067
5949
  var TEXT_PLAIN = "text/plain; charset=UTF-8";
6068
5950
  var setDefaultContentType = (contentType, headers) => {
6069
5951
  return {
@@ -6424,7 +6306,7 @@ var Context = class {
6424
6306
  };
6425
6307
  };
6426
6308
  //#endregion
6427
- //#region ../../node_modules/.pnpm/hono@4.12.19/node_modules/hono/dist/router.js
6309
+ //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/router.js
6428
6310
  var METHODS = [
6429
6311
  "get",
6430
6312
  "post",
@@ -6436,10 +6318,10 @@ var METHODS = [
6436
6318
  var MESSAGE_MATCHER_IS_ALREADY_BUILT = "Can not add a route since the matcher is already built.";
6437
6319
  var UnsupportedPathError = class extends Error {};
6438
6320
  //#endregion
6439
- //#region ../../node_modules/.pnpm/hono@4.12.19/node_modules/hono/dist/utils/constants.js
6321
+ //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/utils/constants.js
6440
6322
  var COMPOSED_HANDLER = "__COMPOSED_HANDLER";
6441
6323
  //#endregion
6442
- //#region ../../node_modules/.pnpm/hono@4.12.19/node_modules/hono/dist/hono-base.js
6324
+ //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/hono-base.js
6443
6325
  var notFoundHandler = (c) => {
6444
6326
  return c.text("404 Not Found", 404);
6445
6327
  };
@@ -6540,7 +6422,7 @@ var Hono$1 = class _Hono {
6540
6422
  handler = async (c, next) => (await compose([], app.errorHandler)(c, () => r.handler(c, next))).res;
6541
6423
  handler[COMPOSED_HANDLER] = r.handler;
6542
6424
  }
6543
- subApp.#addRoute(r.method, r.path, handler);
6425
+ subApp.#addRoute(r.method, r.path, handler, r.basePath);
6544
6426
  });
6545
6427
  return this;
6546
6428
  }
@@ -6657,7 +6539,7 @@ var Hono$1 = class _Hono {
6657
6539
  const pathPrefixLength = mergedPath === "/" ? 0 : mergedPath.length;
6658
6540
  return (request) => {
6659
6541
  const url = new URL(request.url);
6660
- url.pathname = url.pathname.slice(pathPrefixLength) || "/";
6542
+ url.pathname = this.getPath(request).slice(pathPrefixLength) || "/";
6661
6543
  return new Request(url, request);
6662
6544
  };
6663
6545
  })();
@@ -6669,11 +6551,11 @@ var Hono$1 = class _Hono {
6669
6551
  this.#addRoute("ALL", mergePath(path, "*"), handler);
6670
6552
  return this;
6671
6553
  }
6672
- #addRoute(method, path, handler) {
6554
+ #addRoute(method, path, handler, baseRoutePath) {
6673
6555
  method = method.toUpperCase();
6674
6556
  path = mergePath(this._basePath, path);
6675
6557
  const r = {
6676
- basePath: this._basePath,
6558
+ basePath: baseRoutePath !== void 0 ? mergePath(this._basePath, baseRoutePath) : this._basePath,
6677
6559
  path,
6678
6560
  method,
6679
6561
  handler
@@ -6773,7 +6655,7 @@ var Hono$1 = class _Hono {
6773
6655
  };
6774
6656
  };
6775
6657
  //#endregion
6776
- //#region ../../node_modules/.pnpm/hono@4.12.19/node_modules/hono/dist/router/reg-exp-router/matcher.js
6658
+ //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/router/reg-exp-router/matcher.js
6777
6659
  var emptyParam = [];
6778
6660
  function match(method, path) {
6779
6661
  const matchers = this.buildAllMatchers();
@@ -6790,7 +6672,7 @@ function match(method, path) {
6790
6672
  return match2(method, path);
6791
6673
  }
6792
6674
  //#endregion
6793
- //#region ../../node_modules/.pnpm/hono@4.12.19/node_modules/hono/dist/router/reg-exp-router/node.js
6675
+ //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/router/reg-exp-router/node.js
6794
6676
  var LABEL_REG_EXP_STR = "[^/]+";
6795
6677
  var ONLY_WILDCARD_REG_EXP_STR = ".*";
6796
6678
  var TAIL_WILDCARD_REG_EXP_STR = "(?:|/.*)";
@@ -6869,7 +6751,7 @@ var Node$1 = class _Node {
6869
6751
  }
6870
6752
  };
6871
6753
  //#endregion
6872
- //#region ../../node_modules/.pnpm/hono@4.12.19/node_modules/hono/dist/router/reg-exp-router/trie.js
6754
+ //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/router/reg-exp-router/trie.js
6873
6755
  var Trie = class {
6874
6756
  #context = { varIndex: 0 };
6875
6757
  #root = new Node$1();
@@ -6927,7 +6809,7 @@ var Trie = class {
6927
6809
  }
6928
6810
  };
6929
6811
  //#endregion
6930
- //#region ../../node_modules/.pnpm/hono@4.12.19/node_modules/hono/dist/router/reg-exp-router/router.js
6812
+ //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/router/reg-exp-router/router.js
6931
6813
  var nullMatcher = [
6932
6814
  /^$/,
6933
6815
  [],
@@ -7058,7 +6940,7 @@ var RegExpRouter = class {
7058
6940
  }
7059
6941
  };
7060
6942
  //#endregion
7061
- //#region ../../node_modules/.pnpm/hono@4.12.19/node_modules/hono/dist/router/smart-router/router.js
6943
+ //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/router/smart-router/router.js
7062
6944
  var SmartRouter = class {
7063
6945
  name = "SmartRouter";
7064
6946
  #routers = [];
@@ -7105,7 +6987,7 @@ var SmartRouter = class {
7105
6987
  }
7106
6988
  };
7107
6989
  //#endregion
7108
- //#region ../../node_modules/.pnpm/hono@4.12.19/node_modules/hono/dist/router/trie-router/node.js
6990
+ //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/router/trie-router/node.js
7109
6991
  var emptyParams = /* @__PURE__ */ Object.create(null);
7110
6992
  var hasChildren = (children) => {
7111
6993
  for (const _ in children) return true;
@@ -7258,7 +7140,7 @@ var Node = class _Node {
7258
7140
  }
7259
7141
  };
7260
7142
  //#endregion
7261
- //#region ../../node_modules/.pnpm/hono@4.12.19/node_modules/hono/dist/router/trie-router/router.js
7143
+ //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/router/trie-router/router.js
7262
7144
  var TrieRouter = class {
7263
7145
  name = "TrieRouter";
7264
7146
  #node;
@@ -7278,7 +7160,7 @@ var TrieRouter = class {
7278
7160
  }
7279
7161
  };
7280
7162
  //#endregion
7281
- //#region ../../node_modules/.pnpm/hono@4.12.19/node_modules/hono/dist/hono.js
7163
+ //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/hono.js
7282
7164
  var Hono = class extends Hono$1 {
7283
7165
  /**
7284
7166
  * Creates an instance of the Hono class.
@@ -7319,7 +7201,7 @@ object({
7319
7201
  client_secret: string().optional()
7320
7202
  });
7321
7203
  //#endregion
7322
- //#region ../../node_modules/.pnpm/hono@4.12.19/node_modules/hono/dist/utils/stream.js
7204
+ //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/utils/stream.js
7323
7205
  var StreamingApi = class {
7324
7206
  writer;
7325
7207
  encoder;
@@ -7392,7 +7274,7 @@ var StreamingApi = class {
7392
7274
  }
7393
7275
  };
7394
7276
  //#endregion
7395
- //#region ../../node_modules/.pnpm/hono@4.12.19/node_modules/hono/dist/helper/streaming/sse.js
7277
+ //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/helper/streaming/sse.js
7396
7278
  var SSEStreamingApi = class extends StreamingApi {
7397
7279
  constructor(writable, readable) {
7398
7280
  super(writable, readable);
@@ -7416,7 +7298,7 @@ var SSEStreamingApi = class extends StreamingApi {
7416
7298
  }
7417
7299
  };
7418
7300
  //#endregion
7419
- //#region ../../node_modules/.pnpm/@hono+mcp@0.3.0_@modelcontextprotocol+sdk@1.29.0_zod@4.4.3__hono-rate-limiter@0.5.3_hono@4.12.19__hono@4.12.19_zod@4.4.3/node_modules/@hono/mcp/dist/index.js
7301
+ //#region ../../node_modules/.pnpm/@hono+mcp@0.3.0_@modelcontextprotocol+sdk@1.29.0_zod@4.4.3__hono-rate-limiter@0.5.3_hono@4.12.21__hono@4.12.21_zod@4.4.3/node_modules/@hono/mcp/dist/index.js
7420
7302
  let isOldBunVersion = () => {
7421
7303
  const version = typeof Bun !== "undefined" ? Bun.version : void 0;
7422
7304
  if (version === void 0) return false;
@@ -7857,36 +7739,56 @@ var StreamableHTTPTransport = class {
7857
7739
  }
7858
7740
  };
7859
7741
  //#endregion
7860
- //#region ../../node_modules/.pnpm/@hono+node-server@1.19.14_hono@4.12.19/node_modules/@hono/node-server/dist/index.mjs
7742
+ //#region ../../node_modules/.pnpm/@hono+node-server@2.0.3_hono@4.12.21/node_modules/@hono/node-server/dist/index.mjs
7861
7743
  var RequestError = class extends Error {
7862
7744
  constructor(message, options) {
7863
7745
  super(message, options);
7864
7746
  this.name = "RequestError";
7865
7747
  }
7866
7748
  };
7867
- var toRequestError = (e) => {
7749
+ const reValidRequestUrl = /^\/[!#$&-;=?-\[\]_a-z~]*$/;
7750
+ const reDotSegment = /\/\.\.?(?:[/?#]|$)/;
7751
+ const reValidHost = /^[a-z0-9._-]+(?::(?:[1-5]\d{3,4}|[6-9]\d{3}))?$/;
7752
+ const buildUrl = (scheme, host, incomingUrl) => {
7753
+ const url = `${scheme}://${host}${incomingUrl}`;
7754
+ if (!reValidHost.test(host)) {
7755
+ const urlObj = new URL(url);
7756
+ if (urlObj.hostname.length !== host.length && urlObj.hostname !== (host.includes(":") ? host.replace(/:\d+$/, "") : host).toLowerCase()) throw new RequestError("Invalid host header");
7757
+ return urlObj.href;
7758
+ } else if (incomingUrl.length === 0) return url + "/";
7759
+ else {
7760
+ if (incomingUrl.charCodeAt(0) !== 47) throw new RequestError("Invalid URL");
7761
+ if (!reValidRequestUrl.test(incomingUrl) || reDotSegment.test(incomingUrl)) return new URL(url).href;
7762
+ return url;
7763
+ }
7764
+ };
7765
+ const toRequestError = (e) => {
7868
7766
  if (e instanceof RequestError) return e;
7869
7767
  return new RequestError(e.message, { cause: e });
7870
7768
  };
7871
- var GlobalRequest = global.Request;
7769
+ const GlobalRequest = global.Request;
7872
7770
  var Request$1 = class extends GlobalRequest {
7873
7771
  constructor(input, options) {
7874
- if (typeof input === "object" && getRequestCache in input) input = input[getRequestCache]();
7875
- if (typeof options?.body?.getReader !== "undefined") options.duplex ??= "half";
7772
+ if (typeof input === "object" && getRequestCache in input) {
7773
+ const hasReplacementBody = options !== void 0 && "body" in options && options.body != null;
7774
+ if (input[bodyConsumedDirectlyKey] && !hasReplacementBody) throw new TypeError("Cannot construct a Request with a Request object that has already been used.");
7775
+ input = input[getRequestCache]();
7776
+ }
7777
+ if (typeof (options?.body)?.getReader !== "undefined") options.duplex ??= "half";
7876
7778
  super(input, options);
7877
7779
  }
7878
7780
  };
7879
- var newHeadersFromIncoming = (incoming) => {
7781
+ const newHeadersFromIncoming = (incoming) => {
7880
7782
  const headerRecord = [];
7881
7783
  const rawHeaders = incoming.rawHeaders;
7882
- for (let i = 0; i < rawHeaders.length; i += 2) {
7883
- const { [i]: key, [i + 1]: value } = rawHeaders;
7884
- if (key.charCodeAt(0) !== 58) headerRecord.push([key, value]);
7784
+ for (let i = 0, len = rawHeaders.length; i < len; i += 2) {
7785
+ const key = rawHeaders[i];
7786
+ if (key.charCodeAt(0) !== 58) headerRecord.push([key, rawHeaders[i + 1]]);
7885
7787
  }
7886
7788
  return new Headers(headerRecord);
7887
7789
  };
7888
- var wrapBodyStream = Symbol("wrapBodyStream");
7889
- var newRequestFromIncoming = (method, url, headers, incoming, abortController) => {
7790
+ const wrapBodyStream = Symbol("wrapBodyStream");
7791
+ const newRequestFromIncoming = (method, url, headers, incoming, abortController) => {
7890
7792
  const init = {
7891
7793
  method,
7892
7794
  headers,
@@ -7919,15 +7821,162 @@ var newRequestFromIncoming = (method, url, headers, incoming, abortController) =
7919
7821
  } else init.body = Readable.toWeb(incoming);
7920
7822
  return new Request$1(url, init);
7921
7823
  };
7922
- var getRequestCache = Symbol("getRequestCache");
7923
- var requestCache = Symbol("requestCache");
7924
- var incomingKey = Symbol("incomingKey");
7925
- var urlKey = Symbol("urlKey");
7926
- var headersKey = Symbol("headersKey");
7927
- var abortControllerKey = Symbol("abortControllerKey");
7928
- var requestPrototype = {
7824
+ const getRequestCache = Symbol("getRequestCache");
7825
+ const requestCache = Symbol("requestCache");
7826
+ const incomingKey = Symbol("incomingKey");
7827
+ const urlKey = Symbol("urlKey");
7828
+ const methodKey = Symbol("methodKey");
7829
+ const headersKey = Symbol("headersKey");
7830
+ const abortControllerKey = Symbol("abortControllerKey");
7831
+ const getAbortController = Symbol("getAbortController");
7832
+ const abortRequest = Symbol("abortRequest");
7833
+ const bodyBufferKey = Symbol("bodyBuffer");
7834
+ const bodyReadPromiseKey = Symbol("bodyReadPromise");
7835
+ const bodyConsumedDirectlyKey = Symbol("bodyConsumedDirectly");
7836
+ const bodyLockReaderKey = Symbol("bodyLockReader");
7837
+ const abortReasonKey = Symbol("abortReason");
7838
+ const newBodyUnusableError = () => {
7839
+ return /* @__PURE__ */ new TypeError("Body is unusable");
7840
+ };
7841
+ const rejectBodyUnusable = () => {
7842
+ return Promise.reject(newBodyUnusableError());
7843
+ };
7844
+ const textDecoder = new TextDecoder();
7845
+ const consumeBodyDirectOnce = (request) => {
7846
+ if (request[bodyConsumedDirectlyKey]) return rejectBodyUnusable();
7847
+ request[bodyConsumedDirectlyKey] = true;
7848
+ };
7849
+ const toArrayBuffer = (buf) => {
7850
+ return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
7851
+ };
7852
+ const contentType = (request) => {
7853
+ return (request[headersKey] ||= newHeadersFromIncoming(request[incomingKey])).get("content-type") || "";
7854
+ };
7855
+ const methodTokenRegExp = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
7856
+ const normalizeIncomingMethod = (method) => {
7857
+ if (typeof method !== "string" || method.length === 0) return "GET";
7858
+ switch (method) {
7859
+ case "DELETE":
7860
+ case "GET":
7861
+ case "HEAD":
7862
+ case "OPTIONS":
7863
+ case "POST":
7864
+ case "PUT": return method;
7865
+ }
7866
+ const upper = method.toUpperCase();
7867
+ switch (upper) {
7868
+ case "DELETE":
7869
+ case "GET":
7870
+ case "HEAD":
7871
+ case "OPTIONS":
7872
+ case "POST":
7873
+ case "PUT": return upper;
7874
+ default: return method;
7875
+ }
7876
+ };
7877
+ const validateDirectReadMethod = (method) => {
7878
+ if (!methodTokenRegExp.test(method)) return /* @__PURE__ */ new TypeError(`'${method}' is not a valid HTTP method.`);
7879
+ const normalized = method.toUpperCase();
7880
+ if (normalized === "CONNECT" || normalized === "TRACK" || normalized === "TRACE" && method !== "TRACE") return /* @__PURE__ */ new TypeError(`'${method}' HTTP method is unsupported.`);
7881
+ };
7882
+ const readBodyWithFastPath = (request, method, fromBuffer) => {
7883
+ if (request[bodyConsumedDirectlyKey]) return rejectBodyUnusable();
7884
+ const methodName = request.method;
7885
+ if (methodName === "GET" || methodName === "HEAD") return request[getRequestCache]()[method]();
7886
+ const methodValidationError = validateDirectReadMethod(methodName);
7887
+ if (methodValidationError) return Promise.reject(methodValidationError);
7888
+ if (request[requestCache]) {
7889
+ if (methodName !== "TRACE") return request[requestCache][method]();
7890
+ }
7891
+ const alreadyUsedError = consumeBodyDirectOnce(request);
7892
+ if (alreadyUsedError) return alreadyUsedError;
7893
+ const raw = readRawBodyIfAvailable(request);
7894
+ if (raw) {
7895
+ const result = Promise.resolve(fromBuffer(raw, request));
7896
+ request[bodyBufferKey] = void 0;
7897
+ return result;
7898
+ }
7899
+ return readBodyDirect(request).then((buf) => {
7900
+ const result = fromBuffer(buf, request);
7901
+ request[bodyBufferKey] = void 0;
7902
+ return result;
7903
+ });
7904
+ };
7905
+ const readRawBodyIfAvailable = (request) => {
7906
+ const incoming = request[incomingKey];
7907
+ if ("rawBody" in incoming && incoming.rawBody instanceof Buffer) return incoming.rawBody;
7908
+ };
7909
+ const readBodyDirect = (request) => {
7910
+ if (request[bodyBufferKey]) return Promise.resolve(request[bodyBufferKey]);
7911
+ if (request[bodyReadPromiseKey]) return request[bodyReadPromiseKey];
7912
+ const incoming = request[incomingKey];
7913
+ if (Readable.isDisturbed(incoming)) return rejectBodyUnusable();
7914
+ const promise = new Promise((resolve, reject) => {
7915
+ const chunks = [];
7916
+ let settled = false;
7917
+ const finish = (callback) => {
7918
+ if (settled) return;
7919
+ settled = true;
7920
+ cleanup();
7921
+ callback();
7922
+ };
7923
+ const onData = (chunk) => {
7924
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
7925
+ };
7926
+ const onEnd = () => {
7927
+ finish(() => {
7928
+ const buffer = chunks.length === 1 ? chunks[0] : Buffer.concat(chunks);
7929
+ request[bodyBufferKey] = buffer;
7930
+ resolve(buffer);
7931
+ });
7932
+ };
7933
+ const onError = (error) => {
7934
+ finish(() => {
7935
+ reject(error);
7936
+ });
7937
+ };
7938
+ const onClose = () => {
7939
+ if (incoming.readableEnded) {
7940
+ onEnd();
7941
+ return;
7942
+ }
7943
+ finish(() => {
7944
+ if (incoming.errored) {
7945
+ reject(incoming.errored);
7946
+ return;
7947
+ }
7948
+ const reason = request[abortReasonKey];
7949
+ if (reason !== void 0) {
7950
+ reject(reason instanceof Error ? reason : new Error(String(reason)));
7951
+ return;
7952
+ }
7953
+ reject(/* @__PURE__ */ new Error("Client connection prematurely closed."));
7954
+ });
7955
+ };
7956
+ const cleanup = () => {
7957
+ incoming.off("data", onData);
7958
+ incoming.off("end", onEnd);
7959
+ incoming.off("error", onError);
7960
+ incoming.off("close", onClose);
7961
+ request[bodyReadPromiseKey] = void 0;
7962
+ };
7963
+ incoming.on("data", onData);
7964
+ incoming.on("end", onEnd);
7965
+ incoming.on("error", onError);
7966
+ incoming.on("close", onClose);
7967
+ queueMicrotask(() => {
7968
+ if (settled) return;
7969
+ if (incoming.readableEnded) onEnd();
7970
+ else if (incoming.errored) onError(incoming.errored);
7971
+ else if (incoming.destroyed) onClose();
7972
+ });
7973
+ });
7974
+ request[bodyReadPromiseKey] = promise;
7975
+ return promise;
7976
+ };
7977
+ const requestPrototype = {
7929
7978
  get method() {
7930
- return this[incomingKey].method || "GET";
7979
+ return this[methodKey];
7931
7980
  },
7932
7981
  get url() {
7933
7982
  return this[urlKey];
@@ -7935,18 +7984,57 @@ var requestPrototype = {
7935
7984
  get headers() {
7936
7985
  return this[headersKey] ||= newHeadersFromIncoming(this[incomingKey]);
7937
7986
  },
7938
- [Symbol("getAbortController")]() {
7939
- this[getRequestCache]();
7987
+ [abortRequest](reason) {
7988
+ if (this[abortReasonKey] === void 0) this[abortReasonKey] = reason;
7989
+ const abortController = this[abortControllerKey];
7990
+ if (abortController && !abortController.signal.aborted) abortController.abort(reason);
7991
+ },
7992
+ [getAbortController]() {
7993
+ this[abortControllerKey] ||= new AbortController();
7994
+ if (this[abortReasonKey] !== void 0 && !this[abortControllerKey].signal.aborted) this[abortControllerKey].abort(this[abortReasonKey]);
7940
7995
  return this[abortControllerKey];
7941
7996
  },
7942
7997
  [getRequestCache]() {
7943
- this[abortControllerKey] ||= new AbortController();
7944
- return this[requestCache] ||= newRequestFromIncoming(this.method, this[urlKey], this.headers, this[incomingKey], this[abortControllerKey]);
7998
+ const abortController = this[getAbortController]();
7999
+ if (this[requestCache]) return this[requestCache];
8000
+ const method = this.method;
8001
+ if (this[bodyConsumedDirectlyKey] && !(method === "GET" || method === "HEAD")) {
8002
+ this[bodyBufferKey] = void 0;
8003
+ const init = {
8004
+ method: method === "TRACE" ? "GET" : method,
8005
+ headers: this.headers,
8006
+ signal: abortController.signal
8007
+ };
8008
+ if (method !== "TRACE") {
8009
+ init.body = new ReadableStream({ start(c) {
8010
+ c.close();
8011
+ } });
8012
+ init.duplex = "half";
8013
+ }
8014
+ const req = new Request$1(this[urlKey], init);
8015
+ if (method === "TRACE") Object.defineProperty(req, "method", { get() {
8016
+ return "TRACE";
8017
+ } });
8018
+ return this[requestCache] = req;
8019
+ }
8020
+ return this[requestCache] = newRequestFromIncoming(this.method, this[urlKey], this.headers, this[incomingKey], abortController);
8021
+ },
8022
+ get body() {
8023
+ if (!this[bodyConsumedDirectlyKey]) return this[getRequestCache]().body;
8024
+ const request = this[getRequestCache]();
8025
+ if (!this[bodyLockReaderKey] && request.body) this[bodyLockReaderKey] = request.body.getReader();
8026
+ return request.body;
8027
+ },
8028
+ get bodyUsed() {
8029
+ if (this[bodyConsumedDirectlyKey]) return true;
8030
+ if (this[requestCache]) return this[requestCache].bodyUsed;
8031
+ return false;
7945
8032
  }
7946
8033
  };
8034
+ Object.defineProperty(requestPrototype, "signal", { get() {
8035
+ return this[getAbortController]().signal;
8036
+ } });
7947
8037
  [
7948
- "body",
7949
- "bodyUsed",
7950
8038
  "cache",
7951
8039
  "credentials",
7952
8040
  "destination",
@@ -7955,25 +8043,37 @@ var requestPrototype = {
7955
8043
  "redirect",
7956
8044
  "referrer",
7957
8045
  "referrerPolicy",
7958
- "signal",
7959
8046
  "keepalive"
7960
8047
  ].forEach((k) => {
7961
8048
  Object.defineProperty(requestPrototype, k, { get() {
7962
8049
  return this[getRequestCache]()[k];
7963
8050
  } });
7964
8051
  });
7965
- [
7966
- "arrayBuffer",
7967
- "blob",
7968
- "clone",
7969
- "formData",
7970
- "json",
7971
- "text"
7972
- ].forEach((k) => {
8052
+ ["clone", "formData"].forEach((k) => {
7973
8053
  Object.defineProperty(requestPrototype, k, { value: function() {
8054
+ if (this[bodyConsumedDirectlyKey]) {
8055
+ if (k === "clone") throw newBodyUnusableError();
8056
+ return rejectBodyUnusable();
8057
+ }
7974
8058
  return this[getRequestCache]()[k]();
7975
8059
  } });
7976
8060
  });
8061
+ Object.defineProperty(requestPrototype, "text", { value: function() {
8062
+ return readBodyWithFastPath(this, "text", (buf) => textDecoder.decode(buf));
8063
+ } });
8064
+ Object.defineProperty(requestPrototype, "arrayBuffer", { value: function() {
8065
+ return readBodyWithFastPath(this, "arrayBuffer", (buf) => toArrayBuffer(buf));
8066
+ } });
8067
+ Object.defineProperty(requestPrototype, "blob", { value: function() {
8068
+ return readBodyWithFastPath(this, "blob", (buf, request) => {
8069
+ const type = contentType(request);
8070
+ return new Response(buf, type ? { headers: { "content-type": type } } : void 0).blob();
8071
+ });
8072
+ } });
8073
+ Object.defineProperty(requestPrototype, "json", { value: function() {
8074
+ if (this[bodyConsumedDirectlyKey]) return rejectBodyUnusable();
8075
+ return this.text().then(JSON.parse);
8076
+ } });
7977
8077
  Object.defineProperty(requestPrototype, Symbol.for("nodejs.util.inspect.custom"), { value: function(depth, options, inspectFn) {
7978
8078
  return `Request (lightweight) ${inspectFn({
7979
8079
  method: this.method,
@@ -7986,9 +8086,10 @@ Object.defineProperty(requestPrototype, Symbol.for("nodejs.util.inspect.custom")
7986
8086
  })}`;
7987
8087
  } });
7988
8088
  Object.setPrototypeOf(requestPrototype, Request$1.prototype);
7989
- var newRequest = (incoming, defaultHostname) => {
8089
+ const newRequest = (incoming, defaultHostname) => {
7990
8090
  const req = Object.create(requestPrototype);
7991
8091
  req[incomingKey] = incoming;
8092
+ req[methodKey] = normalizeIncomingMethod(incoming.method);
7992
8093
  const incomingUrl = incoming.url || "";
7993
8094
  if (incomingUrl[0] !== "/" && (incomingUrl.startsWith("http://") || incomingUrl.startsWith("https://"))) {
7994
8095
  if (incoming instanceof Http2ServerRequest) throw new RequestError("Absolute URL for :path is not allowed in HTTP/2");
@@ -8006,26 +8107,35 @@ var newRequest = (incoming, defaultHostname) => {
8006
8107
  scheme = incoming.scheme;
8007
8108
  if (!(scheme === "http" || scheme === "https")) throw new RequestError("Unsupported scheme");
8008
8109
  } else scheme = incoming.socket && incoming.socket.encrypted ? "https" : "http";
8009
- const url = new URL(`${scheme}://${host}${incomingUrl}`);
8010
- if (url.hostname.length !== host.length && url.hostname !== host.replace(/:\d+$/, "")) throw new RequestError("Invalid host header");
8011
- req[urlKey] = url.href;
8110
+ try {
8111
+ req[urlKey] = buildUrl(scheme, host, incomingUrl);
8112
+ } catch (e) {
8113
+ if (e instanceof RequestError) throw e;
8114
+ else throw new RequestError("Invalid URL", { cause: e });
8115
+ }
8012
8116
  return req;
8013
8117
  };
8014
- var responseCache = Symbol("responseCache");
8015
- var getResponseCache = Symbol("getResponseCache");
8016
- var cacheKey = Symbol("cache");
8017
- var GlobalResponse = global.Response;
8018
- var Response2 = class _Response {
8118
+ const defaultContentType = "text/plain; charset=UTF-8";
8119
+ const responseCache = Symbol("responseCache");
8120
+ const getResponseCache = Symbol("getResponseCache");
8121
+ const cacheKey = Symbol("cache");
8122
+ const GlobalResponse = global.Response;
8123
+ var Response$1 = class Response$1 {
8019
8124
  #body;
8020
8125
  #init;
8021
8126
  [getResponseCache]() {
8127
+ const cache = this[cacheKey];
8128
+ const liveHeaders = cache && cache[2] instanceof Headers ? cache[2] : void 0;
8022
8129
  delete this[cacheKey];
8023
- return this[responseCache] ||= new GlobalResponse(this.#body, this.#init);
8130
+ return this[responseCache] ||= new GlobalResponse(this.#body, liveHeaders ? {
8131
+ ...this.#init,
8132
+ headers: liveHeaders
8133
+ } : this.#init);
8024
8134
  }
8025
8135
  constructor(body, init) {
8026
8136
  let headers;
8027
8137
  this.#body = body;
8028
- if (init instanceof _Response) {
8138
+ if (init instanceof Response$1) {
8029
8139
  const cachedGlobalResponse = init[responseCache];
8030
8140
  if (cachedGlobalResponse) {
8031
8141
  this.#init = cachedGlobalResponse;
@@ -8033,19 +8143,19 @@ var Response2 = class _Response {
8033
8143
  return;
8034
8144
  } else {
8035
8145
  this.#init = init.#init;
8036
- headers = new Headers(init.#init.headers);
8146
+ headers = new Headers(init.headers);
8037
8147
  }
8038
8148
  } else this.#init = init;
8039
- if (typeof body === "string" || typeof body?.getReader !== "undefined" || body instanceof Blob || body instanceof Uint8Array) this[cacheKey] = [
8149
+ if (body == null || typeof body === "string" || typeof body?.getReader !== "undefined" || body instanceof Blob || body instanceof Uint8Array) this[cacheKey] = [
8040
8150
  init?.status || 200,
8041
- body,
8151
+ body ?? null,
8042
8152
  headers || init?.headers
8043
8153
  ];
8044
8154
  }
8045
8155
  get headers() {
8046
8156
  const cache = this[cacheKey];
8047
8157
  if (cache) {
8048
- if (!(cache[2] instanceof Headers)) cache[2] = new Headers(cache[2] || { "content-type": "text/plain; charset=UTF-8" });
8158
+ if (!(cache[2] instanceof Headers)) cache[2] = new Headers(cache[2] || (cache[1] === null ? void 0 : { "content-type": defaultContentType }));
8049
8159
  return cache[2];
8050
8160
  }
8051
8161
  return this[getResponseCache]().headers;
@@ -8067,7 +8177,7 @@ var Response2 = class _Response {
8067
8177
  "type",
8068
8178
  "url"
8069
8179
  ].forEach((k) => {
8070
- Object.defineProperty(Response2.prototype, k, { get() {
8180
+ Object.defineProperty(Response$1.prototype, k, { get() {
8071
8181
  return this[getResponseCache]()[k];
8072
8182
  } });
8073
8183
  });
@@ -8079,11 +8189,11 @@ var Response2 = class _Response {
8079
8189
  "json",
8080
8190
  "text"
8081
8191
  ].forEach((k) => {
8082
- Object.defineProperty(Response2.prototype, k, { value: function() {
8192
+ Object.defineProperty(Response$1.prototype, k, { value: function() {
8083
8193
  return this[getResponseCache]()[k]();
8084
8194
  } });
8085
8195
  });
8086
- Object.defineProperty(Response2.prototype, Symbol.for("nodejs.util.inspect.custom"), { value: function(depth, options, inspectFn) {
8196
+ Object.defineProperty(Response$1.prototype, Symbol.for("nodejs.util.inspect.custom"), { value: function(depth, options, inspectFn) {
8087
8197
  return `Response (lightweight) ${inspectFn({
8088
8198
  status: this.status,
8089
8199
  headers: this.headers,
@@ -8094,8 +8204,51 @@ Object.defineProperty(Response2.prototype, Symbol.for("nodejs.util.inspect.custo
8094
8204
  depth: depth == null ? null : depth - 1
8095
8205
  })}`;
8096
8206
  } });
8097
- Object.setPrototypeOf(Response2, GlobalResponse);
8098
- Object.setPrototypeOf(Response2.prototype, GlobalResponse.prototype);
8207
+ Object.setPrototypeOf(Response$1, GlobalResponse);
8208
+ Object.setPrototypeOf(Response$1.prototype, GlobalResponse.prototype);
8209
+ const validRedirectUrl = /^https?:\/\/[!#-;=?-[\]_a-z~A-Z]+$/;
8210
+ const parseRedirectUrl = (url) => {
8211
+ if (url instanceof URL) return url.href;
8212
+ if (validRedirectUrl.test(url)) return url;
8213
+ return new URL(url).href;
8214
+ };
8215
+ const validRedirectStatuses = new Set([
8216
+ 301,
8217
+ 302,
8218
+ 303,
8219
+ 307,
8220
+ 308
8221
+ ]);
8222
+ Object.defineProperty(Response$1, "redirect", {
8223
+ value: function redirect(url, status = 302) {
8224
+ if (!validRedirectStatuses.has(status)) throw new RangeError("Invalid status code");
8225
+ return new Response$1(null, {
8226
+ status,
8227
+ headers: { location: parseRedirectUrl(url) }
8228
+ });
8229
+ },
8230
+ writable: true,
8231
+ configurable: true
8232
+ });
8233
+ Object.defineProperty(Response$1, "json", {
8234
+ value: function json(data, init) {
8235
+ const body = JSON.stringify(data);
8236
+ if (body === void 0) throw new TypeError("The data is not JSON serializable");
8237
+ const initHeaders = init?.headers;
8238
+ let headers;
8239
+ if (initHeaders) {
8240
+ headers = new Headers(initHeaders);
8241
+ if (!headers.has("content-type")) headers.set("content-type", "application/json");
8242
+ } else headers = { "content-type": "application/json" };
8243
+ return new Response$1(body, {
8244
+ status: init?.status ?? 200,
8245
+ statusText: init?.statusText,
8246
+ headers
8247
+ });
8248
+ },
8249
+ writable: true,
8250
+ configurable: true
8251
+ });
8099
8252
  async function readWithoutBlocking(readPromise) {
8100
8253
  return Promise.race([readPromise, Promise.resolve().then(() => Promise.resolve(void 0))]);
8101
8254
  }
@@ -8131,23 +8284,23 @@ function writeFromReadableStream(stream, writable) {
8131
8284
  else if (writable.destroyed) return;
8132
8285
  return writeFromReadableStreamDefaultReader(stream.getReader(), writable);
8133
8286
  }
8134
- var buildOutgoingHttpHeaders = (headers) => {
8287
+ const buildOutgoingHttpHeaders = (headers, defaultContentType) => {
8135
8288
  const res = {};
8136
8289
  if (!(headers instanceof Headers)) headers = new Headers(headers ?? void 0);
8137
- const cookies = [];
8138
- for (const [k, v] of headers) if (k === "set-cookie") cookies.push(v);
8139
- else res[k] = v;
8140
- if (cookies.length > 0) res["set-cookie"] = cookies;
8141
- res["content-type"] ??= "text/plain; charset=UTF-8";
8290
+ if (headers.has("set-cookie")) {
8291
+ const cookies = [];
8292
+ for (const [k, v] of headers) if (k === "set-cookie") cookies.push(v);
8293
+ else res[k] = v;
8294
+ if (cookies.length > 0) res["set-cookie"] = cookies;
8295
+ } else for (const [k, v] of headers) res[k] = v;
8296
+ if (defaultContentType) res["content-type"] ??= defaultContentType;
8142
8297
  return res;
8143
8298
  };
8144
- var X_ALREADY_SENT = "x-hono-already-sent";
8145
- if (typeof global.crypto === "undefined") global.crypto = crypto$1;
8146
- var outgoingEnded = Symbol("outgoingEnded");
8147
- var incomingDraining = Symbol("incomingDraining");
8148
- var DRAIN_TIMEOUT_MS = 500;
8149
- var MAX_DRAIN_BYTES = 64 * 1024 * 1024;
8150
- var drainIncoming = (incoming) => {
8299
+ const outgoingEnded = Symbol("outgoingEnded");
8300
+ const incomingDraining = Symbol("incomingDraining");
8301
+ const DRAIN_TIMEOUT_MS = 500;
8302
+ const MAX_DRAIN_BYTES = 64 * 1024 * 1024;
8303
+ const drainIncoming = (incoming) => {
8151
8304
  const incomingWithDrainState = incoming;
8152
8305
  if (incoming.destroyed || incomingWithDrainState[incomingDraining]) return;
8153
8306
  incomingWithDrainState[incomingDraining] = true;
@@ -8180,9 +8333,23 @@ var drainIncoming = (incoming) => {
8180
8333
  incoming.on("error", cleanup);
8181
8334
  incoming.resume();
8182
8335
  };
8183
- var handleRequestError = () => new Response(null, { status: 400 });
8184
- var handleFetchError = (e) => new Response(null, { status: e instanceof Error && (e.name === "TimeoutError" || e.constructor.name === "TimeoutError") ? 504 : 500 });
8185
- var handleResponseError = (e, outgoing) => {
8336
+ const makeCloseHandler = (req, incoming, outgoing, needsBodyCleanup) => () => {
8337
+ if (incoming.errored) req[abortRequest](incoming.errored.toString());
8338
+ else if (!outgoing.writableFinished) req[abortRequest]("Client connection prematurely closed.");
8339
+ if (needsBodyCleanup && !incoming.readableEnded) setTimeout(() => {
8340
+ if (!incoming.readableEnded) setTimeout(() => {
8341
+ drainIncoming(incoming);
8342
+ });
8343
+ });
8344
+ };
8345
+ const isImmediateCacheableResponse = (res) => {
8346
+ if (!(cacheKey in res)) return false;
8347
+ const body = res[cacheKey][1];
8348
+ return body === null || typeof body === "string" || body instanceof Uint8Array;
8349
+ };
8350
+ const handleRequestError = () => new Response(null, { status: 400 });
8351
+ const handleFetchError = (e) => new Response(null, { status: e instanceof Error && (e.name === "TimeoutError" || e.constructor.name === "TimeoutError") ? 504 : 500 });
8352
+ const handleResponseError = (e, outgoing) => {
8186
8353
  const err = e instanceof Error ? e : new Error("unknown error", { cause: e });
8187
8354
  if (err.code === "ERR_STREAM_PREMATURE_CLOSE") console.info("The user aborted a request.");
8188
8355
  else {
@@ -8192,20 +8359,49 @@ var handleResponseError = (e, outgoing) => {
8192
8359
  outgoing.destroy(err);
8193
8360
  }
8194
8361
  };
8195
- var flushHeaders = (outgoing) => {
8362
+ const flushHeaders = (outgoing) => {
8196
8363
  if ("flushHeaders" in outgoing && outgoing.writable) outgoing.flushHeaders();
8197
8364
  };
8198
- var responseViaCache = async (res, outgoing) => {
8365
+ const responseViaCache = async (res, outgoing) => {
8199
8366
  let [status, body, header] = res[cacheKey];
8367
+ if (!header) {
8368
+ if (body === null) {
8369
+ outgoing.writeHead(status);
8370
+ outgoing.end();
8371
+ } else if (typeof body === "string") {
8372
+ outgoing.writeHead(status, {
8373
+ "Content-Type": defaultContentType,
8374
+ "Content-Length": Buffer.byteLength(body)
8375
+ });
8376
+ outgoing.end(body);
8377
+ } else if (body instanceof Uint8Array) {
8378
+ outgoing.writeHead(status, {
8379
+ "Content-Type": defaultContentType,
8380
+ "Content-Length": body.byteLength
8381
+ });
8382
+ outgoing.end(body);
8383
+ } else if (body instanceof Blob) {
8384
+ outgoing.writeHead(status, {
8385
+ "Content-Type": defaultContentType,
8386
+ "Content-Length": body.size
8387
+ });
8388
+ outgoing.end(new Uint8Array(await body.arrayBuffer()));
8389
+ } else {
8390
+ outgoing.writeHead(status, { "Content-Type": defaultContentType });
8391
+ flushHeaders(outgoing);
8392
+ await writeFromReadableStream(body, outgoing)?.catch((e) => handleResponseError(e, outgoing));
8393
+ }
8394
+ outgoing[outgoingEnded]?.();
8395
+ return;
8396
+ }
8200
8397
  let hasContentLength = false;
8201
- if (!header) header = { "content-type": "text/plain; charset=UTF-8" };
8202
- else if (header instanceof Headers) {
8398
+ if (header instanceof Headers) {
8203
8399
  hasContentLength = header.has("content-length");
8204
- header = buildOutgoingHttpHeaders(header);
8400
+ header = buildOutgoingHttpHeaders(header, body === null ? void 0 : defaultContentType);
8205
8401
  } else if (Array.isArray(header)) {
8206
8402
  const headerObj = new Headers(header);
8207
8403
  hasContentLength = headerObj.has("content-length");
8208
- header = buildOutgoingHttpHeaders(headerObj);
8404
+ header = buildOutgoingHttpHeaders(headerObj, body === null ? void 0 : defaultContentType);
8209
8405
  } else for (const key in header) if (key.length === 14 && key.toLowerCase() === "content-length") {
8210
8406
  hasContentLength = true;
8211
8407
  break;
@@ -8216,7 +8412,8 @@ var responseViaCache = async (res, outgoing) => {
8216
8412
  else if (body instanceof Blob) header["Content-Length"] = body.size;
8217
8413
  }
8218
8414
  outgoing.writeHead(status, header);
8219
- if (typeof body === "string" || body instanceof Uint8Array) outgoing.end(body);
8415
+ if (body == null) outgoing.end();
8416
+ else if (typeof body === "string" || body instanceof Uint8Array) outgoing.end(body);
8220
8417
  else if (body instanceof Blob) outgoing.end(new Uint8Array(await body.arrayBuffer()));
8221
8418
  else {
8222
8419
  flushHeaders(outgoing);
@@ -8224,8 +8421,8 @@ var responseViaCache = async (res, outgoing) => {
8224
8421
  }
8225
8422
  outgoing[outgoingEnded]?.();
8226
8423
  };
8227
- var isPromise = (res) => typeof res.then === "function";
8228
- var responseViaResponseObject = async (res, outgoing, options = {}) => {
8424
+ const isPromise = (res) => typeof res.then === "function";
8425
+ const responseViaResponseObject = async (res, outgoing, options = {}) => {
8229
8426
  if (isPromise(res)) if (options.errorHandler) try {
8230
8427
  res = await res;
8231
8428
  } catch (err) {
@@ -8235,7 +8432,7 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
8235
8432
  }
8236
8433
  else res = await res.catch(handleFetchError);
8237
8434
  if (cacheKey in res) return responseViaCache(res, outgoing);
8238
- const resHeaderRecord = buildOutgoingHttpHeaders(res.headers);
8435
+ const resHeaderRecord = buildOutgoingHttpHeaders(res.headers, res.body === null ? void 0 : defaultContentType);
8239
8436
  if (res.body) {
8240
8437
  const reader = res.body.getReader();
8241
8438
  const values = [];
@@ -8275,57 +8472,55 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
8275
8472
  if (values.length === 0) flushHeaders(outgoing);
8276
8473
  await writeFromReadableStreamDefaultReader(reader, outgoing, currentReadPromise);
8277
8474
  }
8278
- } else if (resHeaderRecord[X_ALREADY_SENT]) {} else {
8475
+ } else if (resHeaderRecord["x-hono-already-sent"]) {} else {
8279
8476
  outgoing.writeHead(res.status, resHeaderRecord);
8280
8477
  outgoing.end();
8281
8478
  }
8282
8479
  outgoing[outgoingEnded]?.();
8283
8480
  };
8284
- var getRequestListener = (fetchCallback, options = {}) => {
8481
+ const getRequestListener = (fetchCallback, options = {}) => {
8285
8482
  const autoCleanupIncoming = options.autoCleanupIncoming ?? true;
8286
8483
  if (options.overrideGlobalObjects !== false && global.Request !== Request$1) {
8287
8484
  Object.defineProperty(global, "Request", { value: Request$1 });
8288
- Object.defineProperty(global, "Response", { value: Response2 });
8485
+ Object.defineProperty(global, "Response", { value: Response$1 });
8289
8486
  }
8290
8487
  return async (incoming, outgoing) => {
8291
8488
  let res, req;
8489
+ let needsBodyCleanup = false;
8490
+ let closeHandlerAttached = false;
8491
+ const ensureCloseHandler = () => {
8492
+ if (!req || closeHandlerAttached) return;
8493
+ closeHandlerAttached = true;
8494
+ outgoing.on("close", makeCloseHandler(req, incoming, outgoing, needsBodyCleanup));
8495
+ };
8292
8496
  try {
8293
8497
  req = newRequest(incoming, options.hostname);
8294
- let incomingEnded = !autoCleanupIncoming || incoming.method === "GET" || incoming.method === "HEAD";
8295
- if (!incomingEnded) {
8498
+ needsBodyCleanup = autoCleanupIncoming && !(incoming.method === "GET" || incoming.method === "HEAD");
8499
+ if (needsBodyCleanup) {
8296
8500
  incoming[wrapBodyStream] = true;
8297
- incoming.on("end", () => {
8298
- incomingEnded = true;
8299
- });
8300
8501
  if (incoming instanceof Http2ServerRequest) outgoing[outgoingEnded] = () => {
8301
- if (!incomingEnded) setTimeout(() => {
8302
- if (!incomingEnded) setTimeout(() => {
8303
- drainIncoming(incoming);
8502
+ if (!incoming.readableEnded) setTimeout(() => {
8503
+ if (!incoming.readableEnded) setTimeout(() => {
8504
+ incoming.destroy();
8505
+ outgoing.destroy();
8304
8506
  });
8305
8507
  });
8306
8508
  };
8307
- outgoing.on("finish", () => {
8308
- if (!incomingEnded) drainIncoming(incoming);
8309
- });
8310
8509
  }
8311
- outgoing.on("close", () => {
8312
- if (req[abortControllerKey]) {
8313
- if (incoming.errored) req[abortControllerKey].abort(incoming.errored.toString());
8314
- else if (!outgoing.writableFinished) req[abortControllerKey].abort("Client connection prematurely closed.");
8315
- }
8316
- if (!incomingEnded) setTimeout(() => {
8317
- if (!incomingEnded) setTimeout(() => {
8318
- drainIncoming(incoming);
8319
- });
8320
- });
8321
- });
8322
8510
  res = fetchCallback(req, {
8323
8511
  incoming,
8324
8512
  outgoing
8325
8513
  });
8326
- if (cacheKey in res) return responseViaCache(res, outgoing);
8514
+ if (!isPromise(res) && isImmediateCacheableResponse(res)) {
8515
+ if (needsBodyCleanup && !incoming.readableEnded) outgoing.once("finish", () => {
8516
+ if (!incoming.readableEnded) drainIncoming(incoming);
8517
+ });
8518
+ return responseViaCache(res, outgoing);
8519
+ }
8520
+ ensureCloseHandler();
8327
8521
  } catch (e) {
8328
8522
  if (!res) if (options.errorHandler) {
8523
+ ensureCloseHandler();
8329
8524
  res = await options.errorHandler(req ? e : toRequestError(e));
8330
8525
  if (!res) return;
8331
8526
  } else if (!req) res = handleRequestError();
@@ -8339,16 +8534,126 @@ var getRequestListener = (fetchCallback, options = {}) => {
8339
8534
  }
8340
8535
  };
8341
8536
  };
8342
- var createAdaptorServer = (options) => {
8537
+ globalThis.CloseEvent;
8538
+ const CONNECTION_SYMBOL_KEY = Symbol("CONNECTION_SYMBOL_KEY");
8539
+ const WAIT_FOR_WEBSOCKET_SYMBOL = Symbol("WAIT_FOR_WEBSOCKET_SYMBOL");
8540
+ const responseHeadersToSkip = new Set([
8541
+ "connection",
8542
+ "content-length",
8543
+ "keep-alive",
8544
+ "proxy-authenticate",
8545
+ "proxy-authorization",
8546
+ "te",
8547
+ "trailer",
8548
+ "transfer-encoding",
8549
+ "upgrade",
8550
+ "sec-websocket-accept",
8551
+ "sec-websocket-extensions",
8552
+ "sec-websocket-protocol"
8553
+ ]);
8554
+ const appendResponseHeaders = (headers, responseHeaders) => {
8555
+ if (!responseHeaders) return;
8556
+ responseHeaders.forEach((value, key) => {
8557
+ if (responseHeadersToSkip.has(key.toLowerCase())) return;
8558
+ headers.push(`${key}: ${value}`);
8559
+ });
8560
+ };
8561
+ const rejectUpgradeRequest = (socket, status, responseHeaders) => {
8562
+ const responseLines = ["Connection: close", "Content-Length: 0"];
8563
+ appendResponseHeaders(responseLines, responseHeaders);
8564
+ socket.end(`HTTP/1.1 ${status.toString()} ${STATUS_CODES[status] ?? ""}\r\n${responseLines.join("\r\n")}\r\n\r
8565
+ `);
8566
+ };
8567
+ const createUpgradeRequest = (request) => {
8568
+ const protocol = request.socket.encrypted ? "https" : "http";
8569
+ const url = new URL(request.url ?? "/", `${protocol}://${request.headers.host ?? "localhost"}`);
8570
+ const headers = new Headers();
8571
+ for (const key in request.headers) {
8572
+ const value = request.headers[key];
8573
+ if (!value) continue;
8574
+ headers.append(key, Array.isArray(value) ? value[0] : value);
8575
+ }
8576
+ return new Request(url, { headers });
8577
+ };
8578
+ const setupWebSocket = (options) => {
8579
+ const { server, fetchCallback, wss } = options;
8580
+ const waiterMap = /* @__PURE__ */ new Map();
8581
+ wss.on("connection", (ws, request) => {
8582
+ const waiter = waiterMap.get(request);
8583
+ if (waiter) {
8584
+ waiter.resolve(ws);
8585
+ waiterMap.delete(request);
8586
+ }
8587
+ });
8588
+ const waitForWebSocket = (request, connectionSymbol) => {
8589
+ return new Promise((resolve) => {
8590
+ waiterMap.set(request, {
8591
+ resolve,
8592
+ connectionSymbol
8593
+ });
8594
+ });
8595
+ };
8596
+ server.on("upgrade", async (request, socket, head) => {
8597
+ if (request.headers.upgrade?.toLowerCase() !== "websocket") return;
8598
+ const env = {
8599
+ incoming: request,
8600
+ outgoing: void 0,
8601
+ wss,
8602
+ [WAIT_FOR_WEBSOCKET_SYMBOL]: waitForWebSocket
8603
+ };
8604
+ let status = 400;
8605
+ let responseHeaders;
8606
+ try {
8607
+ const response = await fetchCallback(createUpgradeRequest(request), env);
8608
+ if (response instanceof Response) {
8609
+ status = response.status;
8610
+ responseHeaders = response.headers;
8611
+ }
8612
+ } catch {
8613
+ if (server.listenerCount("upgrade") === 1) rejectUpgradeRequest(socket, 500);
8614
+ return;
8615
+ }
8616
+ const waiter = waiterMap.get(request);
8617
+ if (!waiter || waiter.connectionSymbol !== env[CONNECTION_SYMBOL_KEY]) {
8618
+ waiterMap.delete(request);
8619
+ if (server.listenerCount("upgrade") === 1) rejectUpgradeRequest(socket, status, responseHeaders);
8620
+ return;
8621
+ }
8622
+ const addResponseHeaders = (headers) => {
8623
+ appendResponseHeaders(headers, responseHeaders);
8624
+ };
8625
+ wss.on("headers", addResponseHeaders);
8626
+ try {
8627
+ wss.handleUpgrade(request, socket, head, (ws) => {
8628
+ wss.emit("connection", ws, request);
8629
+ });
8630
+ } finally {
8631
+ wss.off("headers", addResponseHeaders);
8632
+ }
8633
+ });
8634
+ server.on("close", () => {
8635
+ wss.close();
8636
+ });
8637
+ };
8638
+ const createAdaptorServer = (options) => {
8343
8639
  const fetchCallback = options.fetch;
8344
8640
  const requestListener = getRequestListener(fetchCallback, {
8345
8641
  hostname: options.hostname,
8346
8642
  overrideGlobalObjects: options.overrideGlobalObjects,
8347
8643
  autoCleanupIncoming: options.autoCleanupIncoming
8348
8644
  });
8349
- return (options.createServer || createServer)(options.serverOptions || {}, requestListener);
8645
+ const server = (options.createServer || createServer)(options.serverOptions || {}, requestListener);
8646
+ if (options.websocket && options.websocket.server) {
8647
+ if (options.websocket.server.options.noServer !== true) throw new Error("WebSocket server must be created with { noServer: true } option");
8648
+ setupWebSocket({
8649
+ server,
8650
+ fetchCallback,
8651
+ wss: options.websocket.server
8652
+ });
8653
+ }
8654
+ return server;
8350
8655
  };
8351
- var serve = (options, listeningListener) => {
8656
+ const serve = (options, listeningListener) => {
8352
8657
  const server = createAdaptorServer(options);
8353
8658
  server.listen(options?.port ?? 3e3, options.hostname, () => {
8354
8659
  const serverInfo = server.address();
@@ -8357,7 +8662,7 @@ var serve = (options, listeningListener) => {
8357
8662
  return server;
8358
8663
  };
8359
8664
  //#endregion
8360
- //#region ../../node_modules/.pnpm/hono@4.12.19/node_modules/hono/dist/utils/color.js
8665
+ //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/utils/color.js
8361
8666
  function getColorEnabled() {
8362
8667
  const { process, Deno } = globalThis;
8363
8668
  return !(typeof Deno?.noColor === "boolean" ? Deno.noColor : process !== void 0 ? "NO_COLOR" in process?.env : false);
@@ -8374,7 +8679,7 @@ async function getColorEnabledAsync() {
8374
8679
  })() : !getColorEnabled());
8375
8680
  }
8376
8681
  //#endregion
8377
- //#region ../../node_modules/.pnpm/hono@4.12.19/node_modules/hono/dist/middleware/logger/index.js
8682
+ //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/middleware/logger/index.js
8378
8683
  var humanize = (times) => {
8379
8684
  const [delimiter, separator] = [",", "."];
8380
8685
  return times.map((v) => v.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1" + delimiter)).join(separator);
@@ -8413,7 +8718,15 @@ const ENGINE_COMMANDS = new Set([
8413
8718
  "list_tools",
8414
8719
  "search_tools",
8415
8720
  "get_tool",
8416
- "call_tool"
8721
+ "call_tool",
8722
+ "list_resources",
8723
+ "search_resources",
8724
+ "list_resource_templates",
8725
+ "read_resource",
8726
+ "list_prompts",
8727
+ "search_prompts",
8728
+ "get_prompt",
8729
+ "complete"
8417
8730
  ]);
8418
8731
  async function dispatchRemoteCliRequest(request, context) {
8419
8732
  try {
@@ -8464,6 +8777,16 @@ async function dispatch(request, context) {
8464
8777
  ...optionalProp("force", optionalBoolean(request.arguments, "force"))
8465
8778
  })
8466
8779
  };
8780
+ if (request.command === "complete_cli") {
8781
+ const shell = optionalString(request.arguments, "shell") ?? "bash";
8782
+ if (!completionShells.includes(shell)) return [];
8783
+ const engine = new CapletsEngine(context);
8784
+ try {
8785
+ return await engine.completeCliWords(optionalStringArray(request.arguments, "words") ?? [""]);
8786
+ } finally {
8787
+ await engine.close();
8788
+ }
8789
+ }
8467
8790
  if (request.command === "auth_list") return listAuthRows({
8468
8791
  ...optionalProp("configPath", context.configPath),
8469
8792
  ...optionalProp("authDir", context.authDir)
@@ -8580,6 +8903,12 @@ function requiredString(args, key) {
8580
8903
  if (typeof value !== "string" || value.length === 0) throw new CapletsError("REQUEST_INVALID", `${key} must be a non-empty string`);
8581
8904
  return value;
8582
8905
  }
8906
+ function optionalString(args, key) {
8907
+ const value = args[key];
8908
+ if (value === void 0) return;
8909
+ if (typeof value !== "string") throw new CapletsError("REQUEST_INVALID", `${key} must be a string`);
8910
+ return value;
8911
+ }
8583
8912
  function optionalObject(args, key) {
8584
8913
  const value = args[key];
8585
8914
  if (value === void 0) return {};
@@ -9159,6 +9488,9 @@ async function runCli(args, io = {}) {
9159
9488
  throw error;
9160
9489
  }
9161
9490
  }
9491
+ function normalizeCompletionWords(words) {
9492
+ return words.map((word) => word === "__CAPLETS_TRAILING_SPACE__" ? "" : word);
9493
+ }
9162
9494
  function createProgram(io = {}) {
9163
9495
  const writeOut = io.writeOut ?? ((value) => process.stdout.write(value));
9164
9496
  const writeErr = io.writeErr ?? ((value) => process.stderr.write(value));
@@ -9173,7 +9505,27 @@ function createProgram(io = {}) {
9173
9505
  writeErr,
9174
9506
  outputError: (value, write) => write(value)
9175
9507
  });
9176
- program.command("serve").description("Serve configured Caplets as an MCP server.").option("--transport <transport>", "server transport: stdio or http").option("--host <host>", "HTTP bind host").option("--port <port>", "HTTP bind port").option("--path <path>", "HTTP service base path").option("--user <user>", "HTTP Basic Auth username").option("--password <password>", "HTTP Basic Auth password").option("--allow-unauthenticated-http", "allow unauthenticated HTTP serving on non-loopback hosts").option("--trust-proxy", "trust X-Forwarded-* headers from a reverse proxy").action(async (options) => {
9508
+ program.command(cliCommands.completion).description("Print a shell completion script.").argument("<shell>", "completion shell: bash, zsh, fish, powershell, or cmd").action((shell) => {
9509
+ if (!completionShells.includes(shell)) throw new CapletsError("REQUEST_INVALID", "completion shell must be bash, zsh, fish, powershell, or cmd");
9510
+ writeOut(completionScript(shell));
9511
+ });
9512
+ program.command(cliCommands.completeHidden, { hidden: true }).description("Internal shell completion endpoint.").option("--shell <shell>", "completion shell").allowUnknownOption(true).argument("[words...]", "words to complete").action(async (words, options) => {
9513
+ const shell = completionShells.includes(options.shell) ? options.shell : "bash";
9514
+ const remote = remoteClientForCli(io);
9515
+ const configPath = currentConfigPath();
9516
+ const completionWords = normalizeCompletionWords(words);
9517
+ let suggestions = [];
9518
+ try {
9519
+ suggestions = remote ? await remote.request("complete_cli", {
9520
+ shell,
9521
+ words: completionWords
9522
+ }) : await completeCliWords(completionWords, configPath ? { configPath } : {});
9523
+ } catch {
9524
+ suggestions = [];
9525
+ }
9526
+ if (suggestions.length > 0) writeOut(`${suggestions.join("\n")}\n`);
9527
+ });
9528
+ program.command(cliCommands.serve).description("Serve configured Caplets as an MCP server.").option("--transport <transport>", "server transport: stdio or http").option("--host <host>", "HTTP bind host").option("--port <port>", "HTTP bind port").option("--path <path>", "HTTP service base path").option("--user <user>", "HTTP Basic Auth username").option("--password <password>", "HTTP Basic Auth password").option("--allow-unauthenticated-http", "allow unauthenticated HTTP serving on non-loopback hosts").option("--trust-proxy", "trust X-Forwarded-* headers from a reverse proxy").action(async (options) => {
9177
9529
  const resolved = resolveServeOptions(options);
9178
9530
  const configPath = currentConfigPath();
9179
9531
  await (io.serve ?? ((serveOptions) => serveResolvedCaplets(serveOptions, {
@@ -9181,7 +9533,7 @@ function createProgram(io = {}) {
9181
9533
  ...io.authDir ? { authDir: io.authDir } : {}
9182
9534
  }, writeErr)))(resolved);
9183
9535
  });
9184
- program.command("init").description("Create a starter Caplets config file.").option("--force", "overwrite an existing config file").action(async (options) => {
9536
+ program.command(cliCommands.init).description("Create a starter Caplets config file.").option("--force", "overwrite an existing config file").action(async (options) => {
9185
9537
  const remote = remoteClientForCli(io);
9186
9538
  if (remote) {
9187
9539
  writeOut(`Created remote Caplets config at ${(await remote.request("init", { force: Boolean(options.force) })).path}\n`);
@@ -9193,7 +9545,7 @@ function createProgram(io = {}) {
9193
9545
  force: Boolean(options.force)
9194
9546
  })}\n`);
9195
9547
  });
9196
- program.command("list").description("List configured Caplets.").option("--all", "include disabled Caplets").option("--json", "print JSON output").option("--format <format>", "output format: plain, markdown, md, or json", parseOutputFormat).action(async (options) => {
9548
+ program.command(cliCommands.list).description("List configured Caplets.").option("--all", "include disabled Caplets").option("--json", "print JSON output").option("--format <format>", "output format: plain, markdown, md, or json", parseOutputFormat).action(async (options) => {
9197
9549
  const includeDisabled = Boolean(options.all);
9198
9550
  const remote = remoteClientForCli(io);
9199
9551
  if (remote) {
@@ -9212,7 +9564,7 @@ function createProgram(io = {}) {
9212
9564
  }
9213
9565
  writeOut(formatCapletList(rows, options.format ?? "plain"));
9214
9566
  });
9215
- program.command("install").description("Install Caplets from a repo's caplets directory.").argument("<repo>", "local repo path, Git URL, or GitHub owner/repo").argument("[caplets...]", "optional Caplet IDs to install").option("-g, --global", "install to the user Caplets root").option("--force", "overwrite installed Caplets").action(async (repo, capletIds, options) => {
9567
+ program.command(cliCommands.install).description("Install Caplets from a repo's caplets directory.").argument("<repo>", "local repo path, Git URL, or GitHub owner/repo").argument("[caplets...]", "optional Caplet IDs to install").option("-g, --global", "install to the user Caplets root").option("--force", "overwrite installed Caplets").action(async (repo, capletIds, options) => {
9216
9568
  const remote = remoteClientForCli(io);
9217
9569
  if (remote) {
9218
9570
  if (options.global) writeErr("Warning: --global is not supported in remote mode; the server controls the installation destination.\n");
@@ -9231,7 +9583,7 @@ function createProgram(io = {}) {
9231
9583
  });
9232
9584
  for (const caplet of result.installed) writeOut(`Installed ${caplet.id} to ${caplet.destination}\n`);
9233
9585
  });
9234
- const add = program.command("add").description("Add generated Caplet files.");
9586
+ const add = program.command(cliCommands.add).description("Add generated Caplet files.");
9235
9587
  add.command("cli").description("Add a CLI tools Caplet.").argument("<id>", "Caplet ID/display seed").option("--repo <path>", "repository path to inspect").option("--include <items>", "comma-separated generators to include: git,gh,package").option("--command <name>", "single CLI command template to generate").option("-g, --global", "write to the user Caplets root").option("--print", "print generated Caplet text without writing a file").option("--output <path>", "output path").option("--force", "overwrite an existing destination file").action(async (id, options) => {
9236
9588
  const remote = remoteClientForCli(io);
9237
9589
  if (remote) {
@@ -9312,7 +9664,7 @@ function createProgram(io = {}) {
9312
9664
  destinationRoot: addDestinationRoot(options, currentConfigPath())
9313
9665
  }));
9314
9666
  });
9315
- program.command("get-caplet").description("Print a configured Caplet card.").argument("<caplet>", "configured Caplet ID").option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (caplet, options) => {
9667
+ program.command(cliCommands.getCaplet).description("Print a configured Caplet card.").argument("<caplet>", "configured Caplet ID").option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (caplet, options) => {
9316
9668
  await executeOperation(caplet, { operation: "get_caplet" }, {
9317
9669
  writeOut,
9318
9670
  writeErr,
@@ -9323,7 +9675,7 @@ function createProgram(io = {}) {
9323
9675
  format: options.format
9324
9676
  });
9325
9677
  });
9326
- program.command("check-backend").description("Check backend availability for a configured Caplet.").argument("<caplet>", "configured Caplet ID").option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (caplet, options) => {
9678
+ program.command(cliCommands.checkBackend).description("Check backend availability for a configured Caplet.").argument("<caplet>", "configured Caplet ID").option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (caplet, options) => {
9327
9679
  await executeOperation(caplet, { operation: "check_backend" }, {
9328
9680
  writeOut,
9329
9681
  writeErr,
@@ -9334,7 +9686,7 @@ function createProgram(io = {}) {
9334
9686
  format: options.format
9335
9687
  });
9336
9688
  });
9337
- program.command("list-tools").description("List downstream tools for a configured Caplet.").argument("<caplet>", "configured Caplet ID").option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (caplet, options) => {
9689
+ program.command(cliCommands.listTools).description("List downstream tools for a configured Caplet.").argument("<caplet>", "configured Caplet ID").option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (caplet, options) => {
9338
9690
  await executeOperation(caplet, { operation: "list_tools" }, {
9339
9691
  writeOut,
9340
9692
  writeErr,
@@ -9345,7 +9697,7 @@ function createProgram(io = {}) {
9345
9697
  format: options.format
9346
9698
  });
9347
9699
  });
9348
- program.command("search-tools").description("Search downstream tools for a configured Caplet.").argument("<caplet>", "configured Caplet ID").argument("<query>", "search query").option("--limit <n>", "maximum number of tools to return", parsePositiveInteger).option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (caplet, query, options) => {
9700
+ program.command(cliCommands.searchTools).description("Search downstream tools for a configured Caplet.").argument("<caplet>", "configured Caplet ID").argument("<query>", "search query").option("--limit <n>", "maximum number of tools to return", parsePositiveInteger).option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (caplet, query, options) => {
9349
9701
  await executeOperation(caplet, options.limit === void 0 ? {
9350
9702
  operation: "search_tools",
9351
9703
  query
@@ -9363,7 +9715,7 @@ function createProgram(io = {}) {
9363
9715
  format: options.format
9364
9716
  });
9365
9717
  });
9366
- program.command("get-tool").description("Print one downstream tool schema.").argument("<caplet.tool>", "qualified target, split on the first dot").option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (target, options) => {
9718
+ program.command(cliCommands.getTool).description("Print one downstream tool schema.").argument("<caplet.tool>", "qualified target, split on the first dot").option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (target, options) => {
9367
9719
  const { caplet, tool } = parseQualifiedTarget(target);
9368
9720
  await executeOperation(caplet, {
9369
9721
  operation: "get_tool",
@@ -9378,7 +9730,7 @@ function createProgram(io = {}) {
9378
9730
  format: options.format
9379
9731
  });
9380
9732
  });
9381
- program.command("call-tool").description("Call one downstream tool.").argument("<caplet.tool>", "qualified target, split on the first dot").option("--args <json-object>", "JSON object of downstream tool arguments").option("--field <path>", "project a field from structured output", collect, []).option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (target, options) => {
9733
+ program.command(cliCommands.callTool).description("Call one downstream tool.").argument("<caplet.tool>", "qualified target, split on the first dot").option("--args <json-object>", "JSON object of downstream tool arguments").option("--field <path>", "project a field from structured output", collect, []).option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (target, options) => {
9382
9734
  const { caplet, tool } = parseQualifiedTarget(target);
9383
9735
  await executeOperation(caplet, {
9384
9736
  operation: "call_tool",
@@ -9395,7 +9747,119 @@ function createProgram(io = {}) {
9395
9747
  format: options.format
9396
9748
  });
9397
9749
  });
9398
- const config = program.command("config").description("Inspect Caplets config locations.");
9750
+ program.command(cliCommands.listResources).description("List MCP resources for a configured MCP Caplet.").argument("<caplet>").option("--limit <n>", "maximum number of resources to return", parsePositiveInteger).option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (caplet, options) => executeOperation(caplet, options.limit === void 0 ? { operation: "list_resources" } : {
9751
+ operation: "list_resources",
9752
+ limit: options.limit
9753
+ }, {
9754
+ writeOut,
9755
+ writeErr,
9756
+ setExitCode,
9757
+ authDir: io.authDir,
9758
+ env,
9759
+ remote: remoteClientForCli(io),
9760
+ format: options.format
9761
+ }));
9762
+ program.command(cliCommands.searchResources).description("Search MCP resources and resource templates for a configured MCP Caplet.").argument("<caplet>").argument("<query>").option("--limit <n>", "maximum number of matches to return", parsePositiveInteger).option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (caplet, query, options) => executeOperation(caplet, options.limit === void 0 ? {
9763
+ operation: "search_resources",
9764
+ query
9765
+ } : {
9766
+ operation: "search_resources",
9767
+ query,
9768
+ limit: options.limit
9769
+ }, {
9770
+ writeOut,
9771
+ writeErr,
9772
+ setExitCode,
9773
+ authDir: io.authDir,
9774
+ env,
9775
+ remote: remoteClientForCli(io),
9776
+ format: options.format
9777
+ }));
9778
+ program.command(cliCommands.listResourceTemplates).description("List MCP resource templates for a configured MCP Caplet.").argument("<caplet>").option("--limit <n>", "maximum number of templates to return", parsePositiveInteger).option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (caplet, options) => executeOperation(caplet, options.limit === void 0 ? { operation: "list_resource_templates" } : {
9779
+ operation: "list_resource_templates",
9780
+ limit: options.limit
9781
+ }, {
9782
+ writeOut,
9783
+ writeErr,
9784
+ setExitCode,
9785
+ authDir: io.authDir,
9786
+ env,
9787
+ remote: remoteClientForCli(io),
9788
+ format: options.format
9789
+ }));
9790
+ program.command(cliCommands.readResource).description("Read one MCP resource by URI.").argument("<caplet>").argument("<uri>").option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (caplet, uri, options) => executeOperation(caplet, {
9791
+ operation: "read_resource",
9792
+ uri
9793
+ }, {
9794
+ writeOut,
9795
+ writeErr,
9796
+ setExitCode,
9797
+ authDir: io.authDir,
9798
+ env,
9799
+ remote: remoteClientForCli(io),
9800
+ format: options.format
9801
+ }));
9802
+ program.command(cliCommands.listPrompts).description("List MCP prompts for a configured MCP Caplet.").argument("<caplet>").option("--limit <n>", "maximum number of prompts to return", parsePositiveInteger).option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (caplet, options) => executeOperation(caplet, options.limit === void 0 ? { operation: "list_prompts" } : {
9803
+ operation: "list_prompts",
9804
+ limit: options.limit
9805
+ }, {
9806
+ writeOut,
9807
+ writeErr,
9808
+ setExitCode,
9809
+ authDir: io.authDir,
9810
+ env,
9811
+ remote: remoteClientForCli(io),
9812
+ format: options.format
9813
+ }));
9814
+ program.command(cliCommands.searchPrompts).description("Search MCP prompts for a configured MCP Caplet.").argument("<caplet>").argument("<query>").option("--limit <n>", "maximum number of prompts to return", parsePositiveInteger).option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (caplet, query, options) => executeOperation(caplet, options.limit === void 0 ? {
9815
+ operation: "search_prompts",
9816
+ query
9817
+ } : {
9818
+ operation: "search_prompts",
9819
+ query,
9820
+ limit: options.limit
9821
+ }, {
9822
+ writeOut,
9823
+ writeErr,
9824
+ setExitCode,
9825
+ authDir: io.authDir,
9826
+ env,
9827
+ remote: remoteClientForCli(io),
9828
+ format: options.format
9829
+ }));
9830
+ program.command(cliCommands.getPrompt).description("Get one MCP prompt by name.").argument("<caplet.prompt>", "qualified target, split on the first dot").option("--args <json-object>", "JSON object of prompt arguments").option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (target, options) => {
9831
+ const { caplet, tool: prompt } = parseQualifiedTarget(target);
9832
+ await executeOperation(caplet, {
9833
+ operation: "get_prompt",
9834
+ prompt,
9835
+ arguments: parseJsonObjectOption(options.args, "get-prompt --args")
9836
+ }, {
9837
+ writeOut,
9838
+ writeErr,
9839
+ setExitCode,
9840
+ authDir: io.authDir,
9841
+ env,
9842
+ remote: remoteClientForCli(io),
9843
+ format: options.format
9844
+ });
9845
+ });
9846
+ program.command(cliCommands.complete).description("Complete an MCP prompt or resource-template argument.").argument("<caplet>").requiredOption("--argument <name>", "argument name").option("--value <value>", "argument prefix", "").option("--prompt <name>", "prompt name to complete").option("--resource-template <uri-template>", "resource template URI to complete").option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (caplet, options) => executeOperation(caplet, {
9847
+ operation: "complete",
9848
+ ref: completionRefFromOptions(options),
9849
+ argument: {
9850
+ name: options.argument,
9851
+ value: options.value
9852
+ }
9853
+ }, {
9854
+ writeOut,
9855
+ writeErr,
9856
+ setExitCode,
9857
+ authDir: io.authDir,
9858
+ env,
9859
+ remote: remoteClientForCli(io),
9860
+ format: options.format
9861
+ }));
9862
+ const config = program.command(cliCommands.config).description("Inspect Caplets config locations.");
9399
9863
  config.command("path").description("Print the effective user config path.").action(() => {
9400
9864
  writeOut(`${resolveConfigPath(currentConfigPath())}\n`);
9401
9865
  });
@@ -9407,7 +9871,7 @@ function createProgram(io = {}) {
9407
9871
  }
9408
9872
  writeOut(formatConfigPaths(paths, options.format ?? "plain"));
9409
9873
  });
9410
- const auth = program.command("auth").description("Manage OAuth credentials for remote servers.");
9874
+ const auth = program.command(cliCommands.auth).description("Manage OAuth credentials for remote servers.");
9411
9875
  auth.command("login").description("Authenticate a configured remote OAuth server.").argument("<server>", "configured server ID").option("--no-open", "print the authorization URL without opening a browser").action(async (serverId, options) => {
9412
9876
  const remote = remoteClientForCli(io);
9413
9877
  if (remote) {
@@ -9492,7 +9956,15 @@ function remoteCommandForOperation(operation) {
9492
9956
  case "list_tools":
9493
9957
  case "search_tools":
9494
9958
  case "get_tool":
9495
- case "call_tool": return operation;
9959
+ case "call_tool":
9960
+ case "list_resources":
9961
+ case "search_resources":
9962
+ case "list_resource_templates":
9963
+ case "read_resource":
9964
+ case "list_prompts":
9965
+ case "search_prompts":
9966
+ case "get_prompt":
9967
+ case "complete": return operation;
9496
9968
  default: return;
9497
9969
  }
9498
9970
  }
@@ -9540,6 +10012,29 @@ function parseCallToolArgs(value) {
9540
10012
  if (!isPlainObject(parsed)) throw new CapletsError("REQUEST_INVALID", "call-tool --args must be a JSON object");
9541
10013
  return parsed;
9542
10014
  }
10015
+ function parseJsonObjectOption(value, label) {
10016
+ if (value === void 0) return {};
10017
+ let parsed;
10018
+ try {
10019
+ parsed = JSON.parse(value);
10020
+ } catch (error) {
10021
+ throw new CapletsError("REQUEST_INVALID", `${label} must be valid JSON`, error);
10022
+ }
10023
+ if (!isPlainObject(parsed)) throw new CapletsError("REQUEST_INVALID", `${label} must be a JSON object`);
10024
+ return parsed;
10025
+ }
10026
+ function completionRefFromOptions(options) {
10027
+ if (options.prompt && options.resourceTemplate) throw new CapletsError("REQUEST_INVALID", "complete accepts either --prompt or --resource-template, not both");
10028
+ if (options.prompt) return {
10029
+ type: "prompt",
10030
+ name: options.prompt
10031
+ };
10032
+ if (options.resourceTemplate) return {
10033
+ type: "resourceTemplate",
10034
+ uri: options.resourceTemplate
10035
+ };
10036
+ throw new CapletsError("REQUEST_INVALID", "complete requires --prompt or --resource-template");
10037
+ }
9543
10038
  function isPlainObject(value) {
9544
10039
  return value !== null && typeof value === "object" && !Array.isArray(value);
9545
10040
  }
@@ -9670,6 +10165,55 @@ function markdownSummaryForOperation(result, request) {
9670
10165
  "",
9671
10166
  "Use `--format json` to inspect the full structured result."
9672
10167
  ].filter((line) => line !== void 0).join("\n");
10168
+ case "list_resources":
10169
+ case "search_resources": {
10170
+ const resources = Array.isArray(payload.resources) ? payload.resources : [];
10171
+ const templates = Array.isArray(payload.resourceTemplates) ? payload.resourceTemplates : [];
10172
+ const matches = Array.isArray(payload.matches) ? payload.matches : [...resources, ...templates];
10173
+ return [
10174
+ `## MCP resources for \`${id}\``,
10175
+ "",
10176
+ `${matches.length} item${matches.length === 1 ? "" : "s"} found.`,
10177
+ "",
10178
+ ...formatResourceLines(matches, "markdown")
10179
+ ].join("\n");
10180
+ }
10181
+ case "list_resource_templates": {
10182
+ const templates = Array.isArray(payload.resourceTemplates) ? payload.resourceTemplates : [];
10183
+ return [
10184
+ `## MCP resource templates for \`${id}\``,
10185
+ "",
10186
+ ...formatResourceLines(templates, "markdown")
10187
+ ].join("\n");
10188
+ }
10189
+ case "read_resource": return [
10190
+ `## Resource \`${String(request.uri ?? "")}\``,
10191
+ "",
10192
+ summarizeResourceRead(payload),
10193
+ "",
10194
+ "Use `--format json` to inspect all contents."
10195
+ ].join("\n");
10196
+ case "list_prompts":
10197
+ case "search_prompts": {
10198
+ const prompts = Array.isArray(payload.prompts) ? payload.prompts : [];
10199
+ return [
10200
+ `## MCP prompts for \`${id}\``,
10201
+ "",
10202
+ ...formatPromptLines(prompts, "markdown")
10203
+ ].join("\n");
10204
+ }
10205
+ case "get_prompt": return [
10206
+ `## Prompt \`${String(request.caplet)}.${String(request.prompt)}\``,
10207
+ "",
10208
+ summarizePromptResult(payload),
10209
+ "",
10210
+ "Use `--format json` to inspect all messages."
10211
+ ].join("\n");
10212
+ case "complete": return [
10213
+ `## Completion for \`${id}\``,
10214
+ "",
10215
+ summarizeCompletionResult(payload)
10216
+ ].join("\n");
9673
10217
  default: return JSON.stringify(payload, null, 2);
9674
10218
  }
9675
10219
  }
@@ -9726,6 +10270,33 @@ function plainSummaryForOperation(result, request) {
9726
10270
  `Result: ${summarizeCallResult(payload)}`,
9727
10271
  "Use --format json to inspect the full structured result."
9728
10272
  ].filter((line) => Boolean(line)).join("\n");
10273
+ case "list_resources":
10274
+ case "search_resources": {
10275
+ const resources = Array.isArray(payload.resources) ? payload.resources : [];
10276
+ const templates = Array.isArray(payload.resourceTemplates) ? payload.resourceTemplates : [];
10277
+ const matches = Array.isArray(payload.matches) ? payload.matches : [...resources, ...templates];
10278
+ return [`MCP resources for ${id} (${matches.length}):`, ...formatResourceLines(matches, "plain")].join("\n");
10279
+ }
10280
+ case "list_resource_templates": {
10281
+ const templates = Array.isArray(payload.resourceTemplates) ? payload.resourceTemplates : [];
10282
+ return [`MCP resource templates for ${id}:`, ...formatResourceLines(templates, "plain")].join("\n");
10283
+ }
10284
+ case "read_resource": return [
10285
+ `Resource ${String(request.uri ?? "")}`,
10286
+ summarizeResourceRead(payload),
10287
+ "Use --format json to inspect all contents."
10288
+ ].join("\n");
10289
+ case "list_prompts":
10290
+ case "search_prompts": {
10291
+ const prompts = Array.isArray(payload.prompts) ? payload.prompts : [];
10292
+ return [`MCP prompts for ${id}:`, ...formatPromptLines(prompts, "plain")].join("\n");
10293
+ }
10294
+ case "get_prompt": return [
10295
+ `Prompt ${String(request.caplet)}.${String(request.prompt)}`,
10296
+ summarizePromptResult(payload),
10297
+ "Use --format json to inspect all messages."
10298
+ ].join("\n");
10299
+ case "complete": return [`Completion for ${id}`, summarizeCompletionResult(payload)].join("\n");
9729
10300
  default: return JSON.stringify(payload, null, 2);
9730
10301
  }
9731
10302
  }
@@ -9742,6 +10313,44 @@ function formatToolLines(tools, format) {
9742
10313
  return `- ${displayName}${flags ? ` (${flags})` : ""}${tool.description ? ` — ${compactDescription(String(tool.description))}` : ""}`;
9743
10314
  });
9744
10315
  }
10316
+ function formatResourceLines(resources, format) {
10317
+ if (resources.length === 0) return ["- none"];
10318
+ return resources.map((resource) => {
10319
+ if (!isPlainObject(resource)) return `- ${String(resource)}`;
10320
+ const name = String(resource.uri ?? resource.uriTemplate ?? "unknown");
10321
+ const displayName = format === "markdown" ? `\`${name}\`` : name;
10322
+ const label = typeof resource.name === "string" ? ` (${resource.name})` : "";
10323
+ return `- ${typeof resource.kind === "string" ? `${resource.kind}: ` : ""}${displayName}${label}${resource.description ? ` — ${compactDescription(String(resource.description))}` : ""}`;
10324
+ });
10325
+ }
10326
+ function formatPromptLines(prompts, format) {
10327
+ if (prompts.length === 0) return ["- none"];
10328
+ return prompts.map((prompt) => {
10329
+ if (!isPlainObject(prompt)) return `- ${String(prompt)}`;
10330
+ const name = String(prompt.prompt ?? prompt.name ?? "unknown");
10331
+ return `- ${format === "markdown" ? `\`${name}\`` : name}${Array.isArray(prompt.arguments) ? ` (${prompt.arguments.length} args)` : ""}${prompt.description ? ` — ${compactDescription(String(prompt.description))}` : ""}`;
10332
+ });
10333
+ }
10334
+ function summarizeResourceRead(payload) {
10335
+ const contents = Array.isArray(payload.contents) ? payload.contents : [];
10336
+ if (contents.length === 0) return "No contents returned.";
10337
+ const first = contents.find(isPlainObject);
10338
+ if (!first) return `${contents.length} content item${contents.length === 1 ? "" : "s"} returned.`;
10339
+ return previewValue(typeof first.text === "string" ? first.text : first.blob) ?? `${contents.length} content item${contents.length === 1 ? "" : "s"} returned.`;
10340
+ }
10341
+ function summarizePromptResult(payload) {
10342
+ const messages = Array.isArray(payload.messages) ? payload.messages : [];
10343
+ if (messages.length === 0) return "No messages returned.";
10344
+ const first = messages.find(isPlainObject);
10345
+ if (!first) return `${messages.length} message${messages.length === 1 ? "" : "s"} returned.`;
10346
+ return previewValue((isPlainObject(first.content) ? first.content : void 0)?.text ?? first.content) ?? `${messages.length} message${messages.length === 1 ? "" : "s"} returned.`;
10347
+ }
10348
+ function summarizeCompletionResult(payload) {
10349
+ const completion = isPlainObject(payload.completion) ? payload.completion : void 0;
10350
+ const values = Array.isArray(completion?.values) ? completion.values : [];
10351
+ if (values.length > 0) return values.map((value) => `- ${String(value)}`).join("\n");
10352
+ return previewValue(payload) ?? "No completions returned.";
10353
+ }
9745
10354
  function compactDescription(value) {
9746
10355
  const firstParagraph = value.trim().split(/\n\s*\n/u)[0] ?? "";
9747
10356
  const collapsed = (firstParagraph.match(/^.*?(?:[.!?](?=\s|$)|$)/u)?.[0] ?? firstParagraph).replace(/\s+/gu, " ").trim();