@caplets/core 0.18.3 → 0.18.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
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-j9p3L3r1.js";
1
+ import { $ as assertCompleteRequestPrompt, A as CreateMessageResultSchema, At as CAPLETS_ERROR_CODES, B as JSONRPCMessageSchema, C as AjvJsonSchemaValidator, Ct as resolveCapletsRoot, D as CallToolRequestSchema, Dt as discoverCapletFiles, E as toJsonSchemaCompat, Et as resolveProjectConfigPath, F as EmptyResultSchema, G as ListRootsResultSchema, H as ListPromptsRequestSchema, I as ErrorCode, It as __require, J as McpError, K as ListToolsRequestSchema, L as GetPromptRequestSchema, Lt as __toESM, M as CreateTaskResultSchema, Mt as redactSecrets, Nt as toSafeError, O as CallToolResultSchema, Ot as validateCapletFile, P as ElicitResultSchema, Pt as __commonJSMin, R as InitializeRequestSchema, S as assertToolsCallTaskCapability, T as mergeCapabilities, Tt as resolveProjectCapletsRoot, U as ListResourceTemplatesRequestSchema, V as LATEST_PROTOCOL_VERSION, W as ListResourcesRequestSchema, X as SUPPORTED_PROTOCOL_VERSIONS, Y as ReadResourceRequestSchema, Z as SetLevelRequestSchema, _t as loadGlobalConfig, a as resolveCapletsServer, at as getLiteralValue, bt as parseConfig, 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 CapletsError, k as CompleteRequestSchema, kt as SERVER_ID_PATTERN, 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, vt as loadLocalOverlayConfigWithSources, w as Protocol, wt as resolveConfigPath, x as assertClientRequestTaskCapability, y as serializeMessage, yt as loadProjectConfig, z as InitializedNotificationSchema } from "./options-BlNyqF_E.js";
2
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-Cq1z7ci2.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-DRPTunQd.js";
4
4
  import { accessSync, chmodSync, closeSync, constants, copyFileSync, cpSync, existsSync, lstatSync, mkdirSync, mkdtempSync, openSync, readFileSync, readdirSync, readlinkSync, realpathSync, rmSync, statSync, writeFileSync, writeSync } from "node:fs";
5
5
  import { basename, dirname, isAbsolute, join, parse, relative, resolve, sep } from "node:path";
6
6
  import { execFileSync } from "node:child_process";
@@ -1320,7 +1320,7 @@ const EMPTY_COMPLETION_RESULT = { completion: {
1320
1320
  } };
1321
1321
  //#endregion
1322
1322
  //#region package.json
1323
- var version = "0.18.3";
1323
+ var version = "0.18.4";
1324
1324
  //#endregion
1325
1325
  //#region src/serve/session.ts
1326
1326
  var CapletsMcpSession = class {
@@ -4905,7 +4905,7 @@ function isUrlLike(value) {
4905
4905
  //#endregion
4906
4906
  //#region src/cli/auth.ts
4907
4907
  async function loginAuth(serverId, options) {
4908
- const server = findAuthTarget(serverId, loadConfig(options.configPath));
4908
+ const server = findAuthTarget(serverId, options.config ?? loadConfig(options.configPath));
4909
4909
  assertLoginTarget(server, serverId);
4910
4910
  try {
4911
4911
  const flowOptions = {
@@ -4927,40 +4927,64 @@ function logoutAuth(serverId, options) {
4927
4927
  else options.writeOut(`No OAuth credentials found for \`${serverId}\`.\n`);
4928
4928
  }
4929
4929
  function logoutAuthResult(serverId, options) {
4930
- assertLoginTarget(findAuthTarget(serverId, loadConfig(options.configPath)), serverId);
4930
+ assertLoginTarget(findAuthTarget(serverId, options.config ?? loadConfig(options.configPath)), serverId);
4931
4931
  return {
4932
4932
  server: serverId,
4933
4933
  deleted: deleteTokenBundle(serverId, options.authDir)
4934
4934
  };
4935
4935
  }
4936
- function listAuth(options) {
4937
- const rows = listAuthRows(options);
4938
- const format = options.format ?? "plain";
4939
- if (format === "json") {
4940
- options.writeOut(`${JSON.stringify(rows, null, 2)}\n`);
4941
- return;
4936
+ function listAuthRows(options) {
4937
+ return authRowsForTargets(authTargets(loadConfig(options.configPath)), options.authDir);
4938
+ }
4939
+ function listLocalAuthRows(options) {
4940
+ return authRowsForTargets(localAuthTargets(options), options.authDir);
4941
+ }
4942
+ function localAuthTargets(options) {
4943
+ return [...options.source === "project" ? [] : authTargetsForSource("global", options), ...options.source === "global" ? [] : authTargetsForSource("project", options)].filter((target) => !options.source || target.source === options.source);
4944
+ }
4945
+ function localAuthConfigForTarget(options) {
4946
+ assertLoginTarget(localAuthTargets(options).find((candidate) => candidate.server === options.serverId), options.serverId);
4947
+ return loadConfigForSource(options.source, options);
4948
+ }
4949
+ function authTargetsForSource(source, options) {
4950
+ try {
4951
+ return authTargets(loadConfigForSource(source, options)).map((target) => ({
4952
+ ...target,
4953
+ source
4954
+ }));
4955
+ } catch (error) {
4956
+ if (error instanceof CapletsError && error.code === "CONFIG_NOT_FOUND") return [];
4957
+ throw error;
4942
4958
  }
4943
- options.writeOut(formatAuthRows(rows, format));
4944
4959
  }
4945
- function listAuthRows(options) {
4946
- return authTargets(loadConfig(options.configPath)).sort((left, right) => left.server.localeCompare(right.server)).map((server) => {
4947
- const bundle = readTokenBundle(server.server, options.authDir);
4960
+ function loadConfigForSource(source, options) {
4961
+ if (source === "global") return loadGlobalConfig(options.configPath);
4962
+ return loadProjectConfig(options.projectConfigPath);
4963
+ }
4964
+ function authRowsForTargets(targets, authDir) {
4965
+ return targets.sort((left, right) => left.server.localeCompare(right.server)).map((server) => {
4966
+ const bundle = readTokenBundle(server.server, authDir);
4948
4967
  const status = !bundle ? "missing" : isTokenBundleExpired(bundle) ? "expired" : "authenticated";
4949
4968
  return {
4950
4969
  server: server.server,
4951
4970
  status,
4952
4971
  ...bundle?.expiresAt ? { expiresAt: bundle.expiresAt } : {},
4953
- ...bundle?.scope ? { scope: bundle.scope } : {}
4972
+ ...bundle?.scope ? { scope: bundle.scope } : {},
4973
+ ...server.source ? { source: server.source } : {}
4954
4974
  };
4955
4975
  });
4956
4976
  }
4957
4977
  function formatAuthRows(rows, format) {
4958
- if (rows.length === 0) return format === "markdown" ? "## OAuth credentials\n\nNo configured remote OAuth servers found.\n" : "No configured remote OAuth servers found.\n";
4978
+ if (rows.length === 0) return format === "markdown" ? "## OAuth credentials\n\nNo configured OAuth servers found.\n" : "No configured OAuth servers found.\n";
4959
4979
  let output = "";
4960
4980
  if (format === "markdown") output += "## OAuth credentials\n\n";
4961
4981
  else output += "OAuth credentials\n\n";
4962
4982
  for (const row of rows) {
4963
- const details = [row.expiresAt ? `expires ${row.expiresAt}` : void 0, row.scope ? `scope ${row.scope}` : void 0].filter(Boolean).join("; ");
4983
+ const details = [
4984
+ row.source ? `source ${row.source}` : void 0,
4985
+ row.expiresAt ? `expires ${row.expiresAt}` : void 0,
4986
+ row.scope ? `scope ${row.scope}` : void 0
4987
+ ].filter(Boolean).join("; ");
4964
4988
  if (format === "markdown") {
4965
4989
  output += `- \`${row.server}\` — ${row.status}${details ? ` (${details})` : ""}\n`;
4966
4990
  continue;
@@ -4968,6 +4992,7 @@ function formatAuthRows(rows, format) {
4968
4992
  output += [
4969
4993
  row.server,
4970
4994
  ` Status: ${row.status}`,
4995
+ ...row.source ? [` Source: ${row.source}`] : [],
4971
4996
  ...row.expiresAt ? [` Expires: ${row.expiresAt}`] : [],
4972
4997
  ...row.scope ? [` Scope: ${row.scope}`] : []
4973
4998
  ].join("\n") + "\n\n";
@@ -5395,7 +5420,7 @@ function redactRemoteMessage(message) {
5395
5420
  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]");
5396
5421
  }
5397
5422
  //#endregion
5398
- //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/compose.js
5423
+ //#region ../../node_modules/.pnpm/hono@4.12.22/node_modules/hono/dist/compose.js
5399
5424
  var compose = (middleware, onError, onNotFound) => {
5400
5425
  return (context, next) => {
5401
5426
  let index = -1;
@@ -5426,7 +5451,7 @@ var compose = (middleware, onError, onNotFound) => {
5426
5451
  };
5427
5452
  };
5428
5453
  //#endregion
5429
- //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/http-exception.js
5454
+ //#region ../../node_modules/.pnpm/hono@4.12.22/node_modules/hono/dist/http-exception.js
5430
5455
  var HTTPException = class extends Error {
5431
5456
  res;
5432
5457
  status;
@@ -5454,10 +5479,10 @@ var HTTPException = class extends Error {
5454
5479
  }
5455
5480
  };
5456
5481
  //#endregion
5457
- //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/request/constants.js
5482
+ //#region ../../node_modules/.pnpm/hono@4.12.22/node_modules/hono/dist/request/constants.js
5458
5483
  var GET_MATCH_RESULT = /* @__PURE__ */ Symbol();
5459
5484
  //#endregion
5460
- //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/utils/body.js
5485
+ //#region ../../node_modules/.pnpm/hono@4.12.22/node_modules/hono/dist/utils/body.js
5461
5486
  var parseBody = async (request, options = /* @__PURE__ */ Object.create(null)) => {
5462
5487
  const { all = false, dot = false } = options;
5463
5488
  const contentType = (request instanceof HonoRequest ? request.raw.headers : request.headers).get("Content-Type");
@@ -5505,7 +5530,7 @@ var handleParsingNestedValues = (form, key, value) => {
5505
5530
  });
5506
5531
  };
5507
5532
  //#endregion
5508
- //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/utils/url.js
5533
+ //#region ../../node_modules/.pnpm/hono@4.12.22/node_modules/hono/dist/utils/url.js
5509
5534
  var splitPath = (path) => {
5510
5535
  const paths = path.split("/");
5511
5536
  if (paths[0] === "") paths.shift();
@@ -5669,7 +5694,7 @@ var getQueryParams = (url, key) => {
5669
5694
  };
5670
5695
  var decodeURIComponent_ = decodeURIComponent;
5671
5696
  //#endregion
5672
- //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/request.js
5697
+ //#region ../../node_modules/.pnpm/hono@4.12.22/node_modules/hono/dist/request.js
5673
5698
  var tryDecodeURIComponent = (str) => tryDecode(str, decodeURIComponent_);
5674
5699
  var HonoRequest = class {
5675
5700
  /**
@@ -5941,7 +5966,7 @@ var HonoRequest = class {
5941
5966
  }
5942
5967
  };
5943
5968
  //#endregion
5944
- //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/utils/html.js
5969
+ //#region ../../node_modules/.pnpm/hono@4.12.22/node_modules/hono/dist/utils/html.js
5945
5970
  var HtmlEscapedCallbackPhase = {
5946
5971
  Stringify: 1,
5947
5972
  BeforeStream: 2,
@@ -5971,7 +5996,7 @@ var resolveCallback = async (str, phase, preserveCallbacks, context, buffer) =>
5971
5996
  else return resStr;
5972
5997
  };
5973
5998
  //#endregion
5974
- //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/context.js
5999
+ //#region ../../node_modules/.pnpm/hono@4.12.22/node_modules/hono/dist/context.js
5975
6000
  var TEXT_PLAIN = "text/plain; charset=UTF-8";
5976
6001
  var setDefaultContentType = (contentType, headers) => {
5977
6002
  return {
@@ -6332,7 +6357,7 @@ var Context = class {
6332
6357
  };
6333
6358
  };
6334
6359
  //#endregion
6335
- //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/router.js
6360
+ //#region ../../node_modules/.pnpm/hono@4.12.22/node_modules/hono/dist/router.js
6336
6361
  var METHODS = [
6337
6362
  "get",
6338
6363
  "post",
@@ -6344,10 +6369,10 @@ var METHODS = [
6344
6369
  var MESSAGE_MATCHER_IS_ALREADY_BUILT = "Can not add a route since the matcher is already built.";
6345
6370
  var UnsupportedPathError = class extends Error {};
6346
6371
  //#endregion
6347
- //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/utils/constants.js
6372
+ //#region ../../node_modules/.pnpm/hono@4.12.22/node_modules/hono/dist/utils/constants.js
6348
6373
  var COMPOSED_HANDLER = "__COMPOSED_HANDLER";
6349
6374
  //#endregion
6350
- //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/hono-base.js
6375
+ //#region ../../node_modules/.pnpm/hono@4.12.22/node_modules/hono/dist/hono-base.js
6351
6376
  var notFoundHandler = (c) => {
6352
6377
  return c.text("404 Not Found", 404);
6353
6378
  };
@@ -6681,7 +6706,7 @@ var Hono$1 = class _Hono {
6681
6706
  };
6682
6707
  };
6683
6708
  //#endregion
6684
- //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/router/reg-exp-router/matcher.js
6709
+ //#region ../../node_modules/.pnpm/hono@4.12.22/node_modules/hono/dist/router/reg-exp-router/matcher.js
6685
6710
  var emptyParam = [];
6686
6711
  function match(method, path) {
6687
6712
  const matchers = this.buildAllMatchers();
@@ -6698,7 +6723,7 @@ function match(method, path) {
6698
6723
  return match2(method, path);
6699
6724
  }
6700
6725
  //#endregion
6701
- //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/router/reg-exp-router/node.js
6726
+ //#region ../../node_modules/.pnpm/hono@4.12.22/node_modules/hono/dist/router/reg-exp-router/node.js
6702
6727
  var LABEL_REG_EXP_STR = "[^/]+";
6703
6728
  var ONLY_WILDCARD_REG_EXP_STR = ".*";
6704
6729
  var TAIL_WILDCARD_REG_EXP_STR = "(?:|/.*)";
@@ -6777,7 +6802,7 @@ var Node$1 = class _Node {
6777
6802
  }
6778
6803
  };
6779
6804
  //#endregion
6780
- //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/router/reg-exp-router/trie.js
6805
+ //#region ../../node_modules/.pnpm/hono@4.12.22/node_modules/hono/dist/router/reg-exp-router/trie.js
6781
6806
  var Trie = class {
6782
6807
  #context = { varIndex: 0 };
6783
6808
  #root = new Node$1();
@@ -6835,7 +6860,7 @@ var Trie = class {
6835
6860
  }
6836
6861
  };
6837
6862
  //#endregion
6838
- //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/router/reg-exp-router/router.js
6863
+ //#region ../../node_modules/.pnpm/hono@4.12.22/node_modules/hono/dist/router/reg-exp-router/router.js
6839
6864
  var nullMatcher = [
6840
6865
  /^$/,
6841
6866
  [],
@@ -6966,7 +6991,7 @@ var RegExpRouter = class {
6966
6991
  }
6967
6992
  };
6968
6993
  //#endregion
6969
- //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/router/smart-router/router.js
6994
+ //#region ../../node_modules/.pnpm/hono@4.12.22/node_modules/hono/dist/router/smart-router/router.js
6970
6995
  var SmartRouter = class {
6971
6996
  name = "SmartRouter";
6972
6997
  #routers = [];
@@ -7013,7 +7038,7 @@ var SmartRouter = class {
7013
7038
  }
7014
7039
  };
7015
7040
  //#endregion
7016
- //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/router/trie-router/node.js
7041
+ //#region ../../node_modules/.pnpm/hono@4.12.22/node_modules/hono/dist/router/trie-router/node.js
7017
7042
  var emptyParams = /* @__PURE__ */ Object.create(null);
7018
7043
  var hasChildren = (children) => {
7019
7044
  for (const _ in children) return true;
@@ -7166,7 +7191,7 @@ var Node = class _Node {
7166
7191
  }
7167
7192
  };
7168
7193
  //#endregion
7169
- //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/router/trie-router/router.js
7194
+ //#region ../../node_modules/.pnpm/hono@4.12.22/node_modules/hono/dist/router/trie-router/router.js
7170
7195
  var TrieRouter = class {
7171
7196
  name = "TrieRouter";
7172
7197
  #node;
@@ -7186,7 +7211,7 @@ var TrieRouter = class {
7186
7211
  }
7187
7212
  };
7188
7213
  //#endregion
7189
- //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/hono.js
7214
+ //#region ../../node_modules/.pnpm/hono@4.12.22/node_modules/hono/dist/hono.js
7190
7215
  var Hono = class extends Hono$1 {
7191
7216
  /**
7192
7217
  * Creates an instance of the Hono class.
@@ -7227,7 +7252,7 @@ object({
7227
7252
  client_secret: string().optional()
7228
7253
  });
7229
7254
  //#endregion
7230
- //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/utils/stream.js
7255
+ //#region ../../node_modules/.pnpm/hono@4.12.22/node_modules/hono/dist/utils/stream.js
7231
7256
  var StreamingApi = class {
7232
7257
  writer;
7233
7258
  encoder;
@@ -7300,7 +7325,7 @@ var StreamingApi = class {
7300
7325
  }
7301
7326
  };
7302
7327
  //#endregion
7303
- //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/helper/streaming/sse.js
7328
+ //#region ../../node_modules/.pnpm/hono@4.12.22/node_modules/hono/dist/helper/streaming/sse.js
7304
7329
  var SSEStreamingApi = class extends StreamingApi {
7305
7330
  constructor(writable, readable) {
7306
7331
  super(writable, readable);
@@ -7324,7 +7349,7 @@ var SSEStreamingApi = class extends StreamingApi {
7324
7349
  }
7325
7350
  };
7326
7351
  //#endregion
7327
- //#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
7352
+ //#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.22__hono@4.12.22_zod@4.4.3/node_modules/@hono/mcp/dist/index.js
7328
7353
  let isOldBunVersion = () => {
7329
7354
  const version = typeof Bun !== "undefined" ? Bun.version : void 0;
7330
7355
  if (version === void 0) return false;
@@ -7765,7 +7790,7 @@ var StreamableHTTPTransport = class {
7765
7790
  }
7766
7791
  };
7767
7792
  //#endregion
7768
- //#region ../../node_modules/.pnpm/@hono+node-server@2.0.3_hono@4.12.21/node_modules/@hono/node-server/dist/index.mjs
7793
+ //#region ../../node_modules/.pnpm/@hono+node-server@2.0.3_hono@4.12.22/node_modules/@hono/node-server/dist/index.mjs
7769
7794
  var RequestError = class extends Error {
7770
7795
  constructor(message, options) {
7771
7796
  super(message, options);
@@ -8688,7 +8713,7 @@ const serve = (options, listeningListener) => {
8688
8713
  return server;
8689
8714
  };
8690
8715
  //#endregion
8691
- //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/utils/color.js
8716
+ //#region ../../node_modules/.pnpm/hono@4.12.22/node_modules/hono/dist/utils/color.js
8692
8717
  function getColorEnabled() {
8693
8718
  const { process, Deno } = globalThis;
8694
8719
  return !(typeof Deno?.noColor === "boolean" ? Deno.noColor : process !== void 0 ? "NO_COLOR" in process?.env : false);
@@ -8705,7 +8730,7 @@ async function getColorEnabledAsync() {
8705
8730
  })() : !getColorEnabled());
8706
8731
  }
8707
8732
  //#endregion
8708
- //#region ../../node_modules/.pnpm/hono@4.12.21/node_modules/hono/dist/middleware/logger/index.js
8733
+ //#region ../../node_modules/.pnpm/hono@4.12.22/node_modules/hono/dist/middleware/logger/index.js
8709
8734
  var humanize = (times) => {
8710
8735
  const [delimiter, separator] = [",", "."];
8711
8736
  return times.map((v) => v.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1" + delimiter)).join(separator);
@@ -9543,15 +9568,29 @@ function createProgram(io = {}) {
9543
9568
  const completionWords = normalizeCompletionWords(words);
9544
9569
  let suggestions = [];
9545
9570
  try {
9546
- suggestions = remote ? await remote.request("complete_cli", {
9547
- shell,
9548
- words: completionWords
9549
- }) : await completeCliWordsLocally(completionWords, {
9571
+ if (remote) {
9572
+ const localOverlay = loadLocalOverlayForCli(io, () => {});
9573
+ const localSuggestions = await completeCliWordsLocally(completionWords, {
9574
+ ...configPath ? { configPath } : {},
9575
+ projectConfigPath: envProjectConfigPath(env),
9576
+ ...io.authDir ? { authDir: io.authDir } : {},
9577
+ config: localOverlay.config
9578
+ });
9579
+ if (localShadowedCompletionTarget(completionWords, localOverlay.config)) suggestions = localSuggestions;
9580
+ else suggestions = mergeCompletionSuggestions(localSuggestions, await remote.request("complete_cli", {
9581
+ shell,
9582
+ words: completionWords
9583
+ }));
9584
+ } else suggestions = await completeCliWordsLocally(completionWords, {
9550
9585
  ...configPath ? { configPath } : {},
9586
+ projectConfigPath: envProjectConfigPath(env),
9551
9587
  ...io.authDir ? { authDir: io.authDir } : {}
9552
9588
  });
9553
9589
  } catch {
9554
- suggestions = remote ? [] : await completeCliWords(completionWords, configPath ? { configPath } : {});
9590
+ suggestions = remote ? [] : await completeCliWords(completionWords, {
9591
+ ...configPath ? { configPath } : {},
9592
+ projectConfigPath: envProjectConfigPath(env)
9593
+ });
9555
9594
  }
9556
9595
  if (suggestions.length > 0) writeOut(`${suggestions.join("\n")}\n`);
9557
9596
  });
@@ -9563,23 +9602,26 @@ function createProgram(io = {}) {
9563
9602
  ...io.authDir ? { authDir: io.authDir } : {}
9564
9603
  }, writeErr)))(resolved);
9565
9604
  });
9566
- program.command(cliCommands.init).description("Create a starter Caplets config file.").option("--force", "overwrite an existing config file").action(async (options) => {
9567
- const remote = remoteClientForCli(io);
9568
- if (remote) {
9569
- writeOut(`Created remote Caplets config at ${(await remote.request("init", { force: Boolean(options.force) })).path}\n`);
9605
+ program.command(cliCommands.init).description("Create a starter Caplets config file.").option("--project", "create the project Caplets config").option("-g, --global", "create the user Caplets config").option("--remote", "create the remote Caplets config").option("--force", "overwrite an existing config file").action(async (options) => {
9606
+ const target = parseMutationTarget(options);
9607
+ if (target === "remote") {
9608
+ writeOut(`Created remote Caplets config at ${(await requireRemoteClientForTarget(io).request("init", { force: Boolean(options.force) })).path}\n`);
9570
9609
  return;
9571
9610
  }
9572
- const configPath = currentConfigPath();
9573
- writeOut(`Created Caplets config at ${initConfig({
9574
- ...configPath ? { path: configPath } : {},
9611
+ const path = initConfig({
9612
+ path: target === "global" ? resolveConfigPath(currentConfigPath()) : envProjectConfigPath(env),
9575
9613
  force: Boolean(options.force)
9576
- })}\n`);
9614
+ });
9615
+ writeOut(`Created ${localMutationTargetLabel(target, io)}Caplets config at ${path}\n`);
9577
9616
  });
9578
9617
  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) => {
9579
9618
  const includeDisabled = Boolean(options.all);
9580
9619
  const remote = remoteClientForCli(io);
9581
9620
  if (remote) {
9582
- const rows = await remote.request("list", { includeDisabled });
9621
+ const rows = mergeRemoteAndLocalRows(await remote.request("list", { includeDisabled }), tryLoadLocalOverlayForCli(io, writeErr), {
9622
+ includeDisabled,
9623
+ writeErr
9624
+ });
9583
9625
  if (options.json || options.format === "json") {
9584
9626
  writeOut(`${JSON.stringify(rows, null, 2)}\n`);
9585
9627
  return;
@@ -9587,18 +9629,17 @@ function createProgram(io = {}) {
9587
9629
  writeOut(formatCapletList(rows, options.format ?? "plain"));
9588
9630
  return;
9589
9631
  }
9590
- const rows = listCaplets(loadConfigWithSources(currentConfigPath()), { includeDisabled });
9632
+ const rows = listCaplets(loadConfigWithSources(currentConfigPath(), envProjectConfigPath(env)), { includeDisabled });
9591
9633
  if (options.json || options.format === "json") {
9592
9634
  writeOut(`${JSON.stringify(rows, null, 2)}\n`);
9593
9635
  return;
9594
9636
  }
9595
9637
  writeOut(formatCapletList(rows, options.format ?? "plain"));
9596
9638
  });
9597
- 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) => {
9598
- const remote = remoteClientForCli(io);
9599
- if (remote) {
9600
- if (options.global) writeErr("Warning: --global is not supported in remote mode; the server controls the installation destination.\n");
9601
- const result = await remote.request("install", {
9639
+ 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("--project", "install to the project Caplets root").option("-g, --global", "install to the user Caplets root").option("--remote", "install through remote control").option("--force", "overwrite installed Caplets").action(async (repo, capletIds, options) => {
9640
+ const target = parseMutationTarget(options);
9641
+ if (target === "remote") {
9642
+ const result = await requireRemoteClientForTarget(io).request("install", {
9602
9643
  repo,
9603
9644
  capletIds,
9604
9645
  force: Boolean(options.force)
@@ -9609,15 +9650,15 @@ function createProgram(io = {}) {
9609
9650
  const result = installCaplets(repo, {
9610
9651
  capletIds,
9611
9652
  force: Boolean(options.force),
9612
- destinationRoot: options.global ? resolveCapletsRoot(resolveConfigPath(currentConfigPath())) : resolveProjectCapletsRoot()
9653
+ destinationRoot: target === "global" ? resolveCapletsRoot(resolveConfigPath(currentConfigPath())) : envProjectCapletsRoot(env)
9613
9654
  });
9614
- for (const caplet of result.installed) writeOut(`Installed ${caplet.id} to ${caplet.destination}\n`);
9655
+ for (const caplet of result.installed) writeOut(`Installed ${caplet.id} to ${localMutationTargetLabel(target, io)}${caplet.destination}\n`);
9615
9656
  });
9616
9657
  const add = program.command(cliCommands.add).description("Add generated Caplet files.");
9617
- 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) => {
9618
- const remote = remoteClientForCli(io);
9619
- if (remote) {
9620
- writeAddResult(writeOut, "CLI", await remote.request("add", {
9658
+ 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("--project", "write to the project Caplets root").option("-g, --global", "write to the user Caplets root").option("--remote", "add through remote control").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) => {
9659
+ const target = parseMutationTarget(options);
9660
+ if (target === "remote") {
9661
+ writeAddResult(writeOut, "CLI", await requireRemoteClientForTarget(io).request("add", {
9621
9662
  kind: "cli",
9622
9663
  id,
9623
9664
  options: remoteAddOptions(options)
@@ -9626,73 +9667,77 @@ function createProgram(io = {}) {
9626
9667
  }
9627
9668
  const result = addCliCaplet(id, {
9628
9669
  ...options,
9629
- destinationRoot: options.global ? resolveCapletsRoot(resolveConfigPath(currentConfigPath())) : resolveProjectCapletsRoot()
9670
+ destinationRoot: target === "global" ? resolveCapletsRoot(resolveConfigPath(currentConfigPath())) : envProjectCapletsRoot(env)
9630
9671
  });
9631
9672
  if (result.path) {
9632
- writeOut(`Wrote CLI Caplet to ${result.path}\n`);
9673
+ writeOut(`Wrote ${localMutationTargetLabel(target, io)}CLI Caplet to ${result.path}\n`);
9633
9674
  return;
9634
9675
  }
9635
9676
  writeOut(result.text);
9636
9677
  });
9637
- add.command("mcp").description("Add an MCP backend Caplet.").argument("<id>", "Caplet ID/display seed").option("--command <name>", "stdio command").option("--arg <value>", "stdio command argument", collect, []).option("--cwd <path>", "stdio working directory").option("--env <KEY=VALUE>", "stdio environment variable", collect, []).option("--url <url>", "remote MCP server URL").option("--transport <transport>", "remote transport: http or sse").option("--token-env <ENV>", "bearer token environment variable reference").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) => {
9638
- const remote = remoteClientForCli(io);
9639
- if (remote) {
9640
- writeAddResult(writeOut, "MCP", await remote.request("add", {
9678
+ add.command("mcp").description("Add an MCP backend Caplet.").argument("<id>", "Caplet ID/display seed").option("--command <name>", "stdio command").option("--arg <value>", "stdio command argument", collect, []).option("--cwd <path>", "stdio working directory").option("--env <KEY=VALUE>", "stdio environment variable", collect, []).option("--url <url>", "remote MCP server URL").option("--transport <transport>", "remote transport: http or sse").option("--token-env <ENV>", "bearer token environment variable reference").option("--project", "write to the project Caplets root").option("-g, --global", "write to the user Caplets root").option("--remote", "add through remote control").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) => {
9679
+ const target = parseMutationTarget(options);
9680
+ if (target === "remote") {
9681
+ writeAddResult(writeOut, "MCP", await requireRemoteClientForTarget(io).request("add", {
9641
9682
  kind: "mcp",
9642
9683
  id,
9643
9684
  options: remoteAddOptions(options)
9644
9685
  }));
9645
9686
  return;
9646
9687
  }
9647
- writeAddResult(writeOut, "MCP", addMcpCaplet(id, {
9688
+ const result = addMcpCaplet(id, {
9648
9689
  ...options,
9649
- destinationRoot: addDestinationRoot(options, currentConfigPath())
9650
- }));
9690
+ destinationRoot: addDestinationRoot(target, currentConfigPath(), env)
9691
+ });
9692
+ writeAddResult(writeOut, `${localMutationTargetLabel(target, io)}MCP`, result);
9651
9693
  });
9652
- add.command("openapi").description("Add an OpenAPI backend Caplet.").argument("<id>", "Caplet ID/display seed").option("--spec <path-or-url>", "OpenAPI spec path or URL").option("--base-url <url>", "request base URL override").option("--token-env <ENV>", "bearer token environment variable reference").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) => {
9653
- const remote = remoteClientForCli(io);
9654
- if (remote) {
9655
- writeAddResult(writeOut, "OpenAPI", await remote.request("add", {
9694
+ add.command("openapi").description("Add an OpenAPI backend Caplet.").argument("<id>", "Caplet ID/display seed").option("--spec <path-or-url>", "OpenAPI spec path or URL").option("--base-url <url>", "request base URL override").option("--token-env <ENV>", "bearer token environment variable reference").option("--project", "write to the project Caplets root").option("-g, --global", "write to the user Caplets root").option("--remote", "add through remote control").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) => {
9695
+ const target = parseMutationTarget(options);
9696
+ if (target === "remote") {
9697
+ writeAddResult(writeOut, "OpenAPI", await requireRemoteClientForTarget(io).request("add", {
9656
9698
  kind: "openapi",
9657
9699
  id,
9658
9700
  options: remoteAddOptions(options)
9659
9701
  }));
9660
9702
  return;
9661
9703
  }
9662
- writeAddResult(writeOut, "OpenAPI", addOpenApiCaplet(id, {
9704
+ const result = addOpenApiCaplet(id, {
9663
9705
  ...options,
9664
- destinationRoot: addDestinationRoot(options, currentConfigPath())
9665
- }));
9706
+ destinationRoot: addDestinationRoot(target, currentConfigPath(), env)
9707
+ });
9708
+ writeAddResult(writeOut, `${localMutationTargetLabel(target, io)}OpenAPI`, result);
9666
9709
  });
9667
- add.command("graphql").description("Add a GraphQL backend Caplet.").argument("<id>", "Caplet ID/display seed").option("--endpoint-url <url>", "GraphQL endpoint URL").option("--schema <path-or-url>", "GraphQL schema path or URL").option("--introspection", "load schema through endpoint introspection").option("--token-env <ENV>", "bearer token environment variable reference").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) => {
9668
- const remote = remoteClientForCli(io);
9669
- if (remote) {
9670
- writeAddResult(writeOut, "GraphQL", await remote.request("add", {
9710
+ add.command("graphql").description("Add a GraphQL backend Caplet.").argument("<id>", "Caplet ID/display seed").option("--endpoint-url <url>", "GraphQL endpoint URL").option("--schema <path-or-url>", "GraphQL schema path or URL").option("--introspection", "load schema through endpoint introspection").option("--token-env <ENV>", "bearer token environment variable reference").option("--project", "write to the project Caplets root").option("-g, --global", "write to the user Caplets root").option("--remote", "add through remote control").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) => {
9711
+ const target = parseMutationTarget(options);
9712
+ if (target === "remote") {
9713
+ writeAddResult(writeOut, "GraphQL", await requireRemoteClientForTarget(io).request("add", {
9671
9714
  kind: "graphql",
9672
9715
  id,
9673
9716
  options: remoteAddOptions(options)
9674
9717
  }));
9675
9718
  return;
9676
9719
  }
9677
- writeAddResult(writeOut, "GraphQL", addGraphqlCaplet(id, {
9720
+ const result = addGraphqlCaplet(id, {
9678
9721
  ...options,
9679
- destinationRoot: addDestinationRoot(options, currentConfigPath())
9680
- }));
9722
+ destinationRoot: addDestinationRoot(target, currentConfigPath(), env)
9723
+ });
9724
+ writeAddResult(writeOut, `${localMutationTargetLabel(target, io)}GraphQL`, result);
9681
9725
  });
9682
- add.command("http").description("Add an HTTP actions backend Caplet.").argument("<id>", "Caplet ID/display seed").option("--base-url <url>", "HTTP API base URL").option("--action <name:METHOD:/path>", "HTTP action", collect, []).option("--token-env <ENV>", "bearer token environment variable reference").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) => {
9683
- const remote = remoteClientForCli(io);
9684
- if (remote) {
9685
- writeAddResult(writeOut, "HTTP", await remote.request("add", {
9726
+ add.command("http").description("Add an HTTP actions backend Caplet.").argument("<id>", "Caplet ID/display seed").option("--base-url <url>", "HTTP API base URL").option("--action <name:METHOD:/path>", "HTTP action", collect, []).option("--token-env <ENV>", "bearer token environment variable reference").option("--project", "write to the project Caplets root").option("-g, --global", "write to the user Caplets root").option("--remote", "add through remote control").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) => {
9727
+ const target = parseMutationTarget(options);
9728
+ if (target === "remote") {
9729
+ writeAddResult(writeOut, "HTTP", await requireRemoteClientForTarget(io).request("add", {
9686
9730
  kind: "http",
9687
9731
  id,
9688
9732
  options: remoteAddOptions(options)
9689
9733
  }));
9690
9734
  return;
9691
9735
  }
9692
- writeAddResult(writeOut, "HTTP", addHttpCaplet(id, {
9736
+ const result = addHttpCaplet(id, {
9693
9737
  ...options,
9694
- destinationRoot: addDestinationRoot(options, currentConfigPath())
9695
- }));
9738
+ destinationRoot: addDestinationRoot(target, currentConfigPath(), env)
9739
+ });
9740
+ writeAddResult(writeOut, `${localMutationTargetLabel(target, io)}HTTP`, result);
9696
9741
  });
9697
9742
  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) => {
9698
9743
  await executeOperation(caplet, { operation: "get_caplet" }, {
@@ -9894,7 +9939,7 @@ function createProgram(io = {}) {
9894
9939
  writeOut(`${resolveConfigPath(currentConfigPath())}\n`);
9895
9940
  });
9896
9941
  config.command("paths").description("Print resolved Caplets config, root, and auth paths.").option("--json", "print JSON output").option("--format <format>", "output format: plain, markdown, md, or json", parseOutputFormat).action((options) => {
9897
- const paths = resolveCliConfigPaths(currentConfigPath(), io.authDir);
9942
+ const paths = resolveCliConfigPaths(currentConfigPath(), envProjectConfigPath(env), io.authDir);
9898
9943
  if (options.json || options.format === "json") {
9899
9944
  writeOut(`${JSON.stringify(paths, null, 2)}\n`);
9900
9945
  return;
@@ -9902,60 +9947,59 @@ function createProgram(io = {}) {
9902
9947
  writeOut(formatConfigPaths(paths, options.format ?? "plain"));
9903
9948
  });
9904
9949
  const auth = program.command(cliCommands.auth).description("Manage OAuth credentials for remote servers.");
9905
- 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) => {
9906
- const remote = remoteClientForCli(io);
9907
- if (remote) {
9908
- const started = await remote.request("auth_login_start", { server: serverId });
9909
- if (started.authorizationUrl) {
9910
- writeOut(`Open this URL to authorize ${serverId}:\n${started.authorizationUrl}\n`);
9911
- if (options.open !== false) await openBrowser(started.authorizationUrl);
9912
- writeOut("Complete authentication in your browser. The server callback will store credentials.\n");
9913
- return;
9914
- }
9915
- if (started.authenticated) writeOut(`Authenticated \`${serverId}\`.\n`);
9950
+ auth.command("login").description("Authenticate a configured remote OAuth server.").argument("<server>", "configured server ID").option("--project", "authenticate using the project Caplets config").option("-g, --global", "authenticate using the user Caplets config").option("--remote", "authenticate using the remote server auth store").option("--no-open", "print the authorization URL without opening a browser").action(async (serverId, options) => {
9951
+ const target = await resolveAuthTarget(serverId, options, io);
9952
+ if (target === "remote") {
9953
+ await remoteAuthLogin(requireRemoteClientForTarget(io), serverId, options.open !== false, writeOut);
9916
9954
  return;
9917
9955
  }
9918
9956
  const configPath = currentConfigPath();
9957
+ const projectConfigPath = envProjectConfigPath(env);
9919
9958
  await loginAuth(serverId, {
9920
9959
  noOpen: options.open === false,
9921
9960
  writeOut,
9922
9961
  writeErr,
9923
9962
  ...configPath ? { configPath } : {},
9963
+ ...projectConfigPath ? { projectConfigPath } : {},
9964
+ config: localAuthConfigForTarget({
9965
+ serverId,
9966
+ ...configPath ? { configPath } : {},
9967
+ ...projectConfigPath ? { projectConfigPath } : {},
9968
+ source: target
9969
+ }),
9924
9970
  ...io.authDir ? { authDir: io.authDir } : {}
9925
9971
  });
9926
9972
  });
9927
- auth.command("logout").description("Delete stored OAuth credentials for a server.").argument("<server>", "configured server ID").action(async (serverId) => {
9928
- const remote = remoteClientForCli(io);
9929
- if (remote) {
9930
- writeOut((await remote.request("auth_logout", { server: serverId })).deleted ? `Deleted remote OAuth credentials for \`${serverId}\`.\n` : `No remote OAuth credentials found for \`${serverId}\`.\n`);
9973
+ auth.command("logout").description("Delete stored OAuth credentials for a server.").argument("<server>", "configured server ID").option("--project", "delete credentials for the project Caplets config target").option("-g, --global", "delete credentials for the user Caplets config target").option("--remote", "delete credentials from the remote server auth store").action(async (serverId, options) => {
9974
+ const target = await resolveAuthTarget(serverId, options, io);
9975
+ if (target === "remote") {
9976
+ writeOut((await requireRemoteClientForTarget(io).request("auth_logout", { server: serverId })).deleted ? `Deleted remote OAuth credentials for \`${serverId}\`.\n` : `No remote OAuth credentials found for \`${serverId}\`.\n`);
9931
9977
  return;
9932
9978
  }
9933
9979
  const configPath = currentConfigPath();
9980
+ const projectConfigPath = envProjectConfigPath(env);
9934
9981
  logoutAuth(serverId, {
9935
9982
  writeOut,
9936
9983
  ...configPath ? { configPath } : {},
9984
+ config: localAuthConfigForTarget({
9985
+ serverId,
9986
+ ...configPath ? { configPath } : {},
9987
+ ...projectConfigPath ? { projectConfigPath } : {},
9988
+ source: target
9989
+ }),
9937
9990
  ...io.authDir ? { authDir: io.authDir } : {}
9938
9991
  });
9939
9992
  });
9940
- auth.command("list").description("List servers with stored OAuth credentials.").option("--json", "print JSON output").option("--format <format>", "output format: plain, markdown, md, or json", parseOutputFormat).action(async (options) => {
9993
+ auth.command("list").description("List servers with stored OAuth credentials.").option("--json", "print JSON output").option("--format <format>", "output format: plain, markdown, md, or json", parseOutputFormat).option("--project", "list auth targets from the project Caplets config").option("-g, --global", "list auth targets from the user Caplets config").option("--remote", "list auth targets from the remote server auth store").action(async (options) => {
9941
9994
  const configPath = currentConfigPath();
9995
+ const projectConfigPath = envProjectConfigPath(env);
9942
9996
  const format = options.json || options.format === "json" ? "json" : options.format ?? "plain";
9943
- const remote = remoteClientForCli(io);
9944
- if (remote) {
9945
- const rows = await remote.request("auth_list", {});
9946
- if (format === "json") {
9947
- writeOut(`${JSON.stringify(rows, null, 2)}\n`);
9948
- return;
9949
- }
9950
- writeOut(formatAuthRows(rows, format));
9997
+ const rows = await authListRowsForCli(parseAuthFlagTarget(options), io, configPath, projectConfigPath);
9998
+ if (format === "json") {
9999
+ writeOut(`${JSON.stringify(rows, null, 2)}\n`);
9951
10000
  return;
9952
10001
  }
9953
- listAuth({
9954
- writeOut,
9955
- format,
9956
- ...configPath ? { configPath } : {},
9957
- ...io.authDir ? { authDir: io.authDir } : {}
9958
- });
10002
+ writeOut(formatAuthRows(rows, format));
9959
10003
  });
9960
10004
  return program;
9961
10005
  }
@@ -9999,12 +10043,90 @@ function remoteCommandForOperation(operation) {
9999
10043
  }
10000
10044
  }
10001
10045
  function remoteAddOptions(options) {
10002
- const { output, print, global, destinationRoot, ...remoteOptions } = options;
10003
- if (global) throw new CapletsError("REQUEST_INVALID", "--global is not supported in remote mode; the server controls the add destination.");
10046
+ const { output, print, global, project, remote, destinationRoot, ...remoteOptions } = options;
10004
10047
  if (print) throw new CapletsError("REQUEST_INVALID", "--print is not supported in remote mode; the server controls add output.");
10005
10048
  if (output !== void 0) throw new CapletsError("REQUEST_INVALID", "--output is not supported in remote mode; the server controls the add destination.");
10006
10049
  return remoteOptions;
10007
10050
  }
10051
+ function parseMutationTarget(options) {
10052
+ const selected = [
10053
+ options.project ? "--project" : void 0,
10054
+ options.global ? "--global" : void 0,
10055
+ options.remote ? "--remote" : void 0
10056
+ ].filter((value) => value !== void 0);
10057
+ if (selected.length > 1) throw new CapletsError("REQUEST_INVALID", `Cannot combine mutation target flags: ${selected.join(", ")}`);
10058
+ if (options.global) return "global";
10059
+ if (options.remote) return "remote";
10060
+ return "project";
10061
+ }
10062
+ function localMutationTargetLabel(target, io) {
10063
+ return remoteClientForCli(io) ? `${target} ` : "";
10064
+ }
10065
+ function parseAuthFlagTarget(options) {
10066
+ const selected = [
10067
+ options.project ? "--project" : void 0,
10068
+ options.global ? "--global" : void 0,
10069
+ options.remote ? "--remote" : void 0
10070
+ ].filter((value) => value !== void 0);
10071
+ if (selected.length > 1) throw new CapletsError("REQUEST_INVALID", `Cannot combine auth target flags: ${selected.join(", ")}`);
10072
+ if (options.project) return "project";
10073
+ if (options.global) return "global";
10074
+ if (options.remote) return "remote";
10075
+ }
10076
+ async function resolveAuthTarget(serverId, options, io) {
10077
+ const explicit = parseAuthFlagTarget(options);
10078
+ if (explicit) return explicit;
10079
+ const env = io.env ?? process.env;
10080
+ const configPath = envConfigPath(env);
10081
+ const projectConfigPath = envProjectConfigPath(env);
10082
+ const matches = localAuthTargets({
10083
+ ...configPath ? { configPath } : {},
10084
+ ...projectConfigPath ? { projectConfigPath } : {}
10085
+ }).filter((target) => target.server === serverId).map((target) => target.source);
10086
+ const remote = remoteClientForCli(io);
10087
+ if (remote) {
10088
+ if (matches.length === 0) matches.push("remote");
10089
+ else if ((await remoteAuthRows(remote)).some((row) => row.server === serverId)) matches.push("remote");
10090
+ }
10091
+ const unique = [...new Set(matches)];
10092
+ if (unique.length === 1) return unique[0];
10093
+ if (unique.length > 1) throw new CapletsError("REQUEST_INVALID", `Auth target \`${serverId}\` exists in multiple scopes. Pass --project, --global, or --remote.`);
10094
+ throw new CapletsError("SERVER_NOT_FOUND", `Server ${serverId} is not configured for OAuth`);
10095
+ }
10096
+ async function authListRowsForCli(target, io, configPath, projectConfigPath) {
10097
+ if (target === "remote") return remoteAuthRows(requireRemoteClientForTarget(io));
10098
+ const localRows = listLocalAuthRows({
10099
+ ...configPath ? { configPath } : {},
10100
+ ...projectConfigPath ? { projectConfigPath } : {},
10101
+ ...io.authDir ? { authDir: io.authDir } : {},
10102
+ ...target ? { source: target } : {}
10103
+ });
10104
+ if (target) return localRows;
10105
+ const remote = remoteClientForCli(io);
10106
+ if (!remote) return localRows;
10107
+ return [...localRows, ...await remoteAuthRows(remote)].sort((left, right) => left.server.localeCompare(right.server));
10108
+ }
10109
+ async function remoteAuthRows(remote) {
10110
+ return (await remote.request("auth_list", {})).map((row) => ({
10111
+ ...row,
10112
+ source: "remote"
10113
+ }));
10114
+ }
10115
+ async function remoteAuthLogin(remote, serverId, open, writeOut) {
10116
+ const started = await remote.request("auth_login_start", { server: serverId });
10117
+ if (started.authorizationUrl) {
10118
+ writeOut(`Open this URL to authorize ${serverId}:\n${started.authorizationUrl}\n`);
10119
+ if (open) await openBrowser(started.authorizationUrl);
10120
+ writeOut("Complete authentication in your browser. The server callback will store credentials.\n");
10121
+ return;
10122
+ }
10123
+ if (started.authenticated) writeOut(`Authenticated \`${serverId}\`.\n`);
10124
+ }
10125
+ function requireRemoteClientForTarget(io) {
10126
+ const remote = remoteClientForCli(io);
10127
+ if (!remote) throw new CapletsError("REQUEST_INVALID", "--remote requires CAPLETS_MODE=remote and CAPLETS_SERVER_URL");
10128
+ return remote;
10129
+ }
10008
10130
  function collect(value, previous) {
10009
10131
  previous.push(value);
10010
10132
  return previous;
@@ -10041,8 +10163,10 @@ function parseQualifiedTarget(capletOrTarget, toolArgument) {
10041
10163
  async function completeCliWordsLocally(words, options) {
10042
10164
  const engine = new CapletsEngine({
10043
10165
  ...options.configPath ? { configPath: options.configPath } : {},
10166
+ ...options.projectConfigPath ? { projectConfigPath: options.projectConfigPath } : {},
10044
10167
  ...options.authDir ? { authDir: options.authDir } : {},
10045
- watch: false
10168
+ watch: false,
10169
+ ...options.config ? { configLoader: () => options.config } : {}
10046
10170
  });
10047
10171
  try {
10048
10172
  return await engine.completeCliWords(words);
@@ -10050,6 +10174,34 @@ async function completeCliWordsLocally(words, options) {
10050
10174
  await engine.close();
10051
10175
  }
10052
10176
  }
10177
+ function mergeCompletionSuggestions(...groups) {
10178
+ return [...new Set(groups.flat())];
10179
+ }
10180
+ function localShadowedCompletionTarget(words, config) {
10181
+ const command = words[0];
10182
+ const target = words[1];
10183
+ if (!command || !target || target.startsWith("-")) return;
10184
+ const qualifiedCommands = new Set([
10185
+ cliCommands.getTool,
10186
+ cliCommands.callTool,
10187
+ cliCommands.getPrompt
10188
+ ]);
10189
+ const capletCommands = new Set([
10190
+ cliCommands.getCaplet,
10191
+ cliCommands.checkBackend,
10192
+ cliCommands.listTools,
10193
+ cliCommands.searchTools,
10194
+ cliCommands.listResources,
10195
+ cliCommands.searchResources,
10196
+ cliCommands.listResourceTemplates,
10197
+ cliCommands.readResource,
10198
+ cliCommands.listPrompts,
10199
+ cliCommands.searchPrompts,
10200
+ cliCommands.complete
10201
+ ]);
10202
+ const caplet = qualifiedCommands.has(command) ? target.slice(0, target.includes(".") ? target.indexOf(".") : target.length) : capletCommands.has(command) ? target : void 0;
10203
+ return caplet && hasEnabledCaplet(config, caplet) ? caplet : void 0;
10204
+ }
10053
10205
  function parseCallToolArgs(value) {
10054
10206
  if (value === void 0) return {};
10055
10207
  let parsed;
@@ -10090,6 +10242,11 @@ function isPlainObject(value) {
10090
10242
  async function executeOperation(caplet, request, io) {
10091
10243
  const command = remoteCommandForOperation(request.operation);
10092
10244
  if (io.remote && command) {
10245
+ const localOverlay = tryLoadLocalOverlayForCli(io, io.writeErr);
10246
+ if (localOverlay && hasEnabledCaplet(localOverlay.config, caplet)) {
10247
+ await executeLocalOperation(caplet, request, io, localOverlay.config);
10248
+ return;
10249
+ }
10093
10250
  const result = await io.remote.request(command, {
10094
10251
  caplet,
10095
10252
  request
@@ -10102,12 +10259,119 @@ async function executeOperation(caplet, request, io) {
10102
10259
  if (isPlainObject(result) && result.isError === true) io.setExitCode(1);
10103
10260
  return;
10104
10261
  }
10262
+ await executeLocalOperation(caplet, request, io);
10263
+ }
10264
+ function loadLocalOverlayForCli(io, writeErr) {
10265
+ const env = io.env ?? process.env;
10266
+ const overlay = loadLocalOverlayConfigWithSources(resolveConfigPath(envConfigPath(env)), envProjectConfigPath(env));
10267
+ for (const warning of overlay.warnings) writeErr(`Warning: ${warning.kind} at ${warning.path}: ${warning.message}\n`);
10268
+ return overlay;
10269
+ }
10270
+ function tryLoadLocalOverlayForCli(io, writeErr) {
10271
+ try {
10272
+ return loadLocalOverlayForCli(io, writeErr);
10273
+ } catch (error) {
10274
+ writeErr(`Warning: Could not load local Caplets overlay: ${formatErrorMessage(error)}\n`);
10275
+ return loadPartialLocalOverlayForCli(io, writeErr);
10276
+ }
10277
+ }
10278
+ function loadPartialLocalOverlayForCli(io, writeErr) {
10279
+ const env = io.env ?? process.env;
10280
+ const configPath = resolveConfigPath(envConfigPath(env));
10281
+ const projectConfigPath = envProjectConfigPath(env);
10282
+ const absentProjectPath = join(dirname(configPath), ".caplets-overlay-recovery", "config.json");
10283
+ const absentGlobalPath = join(dirname(projectConfigPath), ".caplets-overlay-recovery", "config.json");
10284
+ const globalOverlay = tryLoadPartialOverlayLayer("global", configPath, absentProjectPath, writeErr);
10285
+ const projectOverlay = tryLoadPartialOverlayLayer("project", absentGlobalPath, projectConfigPath, writeErr);
10286
+ if (!globalOverlay) return projectOverlay;
10287
+ if (!projectOverlay) return globalOverlay;
10288
+ return mergePartialLocalOverlays(globalOverlay, projectOverlay);
10289
+ }
10290
+ function tryLoadPartialOverlayLayer(label, configPath, projectConfigPath, writeErr) {
10291
+ try {
10292
+ const overlay = loadLocalOverlayConfigWithSources(configPath, projectConfigPath);
10293
+ for (const warning of overlay.warnings) writeErr(`Warning: ${warning.kind} at ${warning.path}: ${warning.message}\n`);
10294
+ return overlay;
10295
+ } catch (error) {
10296
+ writeErr(`Warning: Could not load ${label} Caplets overlay: ${formatErrorMessage(error)}\n`);
10297
+ return;
10298
+ }
10299
+ }
10300
+ function mergePartialLocalOverlays(globalOverlay, projectOverlay) {
10301
+ const config = { ...globalOverlay.config };
10302
+ const sources = { ...globalOverlay.sources };
10303
+ const shadows = { ...globalOverlay.shadows };
10304
+ for (const kind of capletConfigKinds) config[kind] = { ...globalOverlay.config[kind] };
10305
+ for (const kind of capletConfigKinds) for (const id of Object.keys(projectOverlay.config[kind])) {
10306
+ removeCapletFromPartialOverlay(config, sources, shadows, id);
10307
+ config[kind][id] = projectOverlay.config[kind][id];
10308
+ }
10309
+ for (const [id, source] of Object.entries(projectOverlay.sources)) sources[id] = source;
10310
+ for (const [id, shadowedSources] of Object.entries(projectOverlay.shadows)) shadows[id] = [...shadows[id] ?? [], ...shadowedSources];
10311
+ return {
10312
+ config,
10313
+ sources,
10314
+ shadows,
10315
+ warnings: [...globalOverlay.warnings, ...projectOverlay.warnings]
10316
+ };
10317
+ }
10318
+ const capletConfigKinds = [
10319
+ "mcpServers",
10320
+ "openapiEndpoints",
10321
+ "graphqlEndpoints",
10322
+ "httpApis",
10323
+ "cliTools",
10324
+ "capletSets"
10325
+ ];
10326
+ function removeCapletFromPartialOverlay(config, sources, shadows, id) {
10327
+ for (const kind of capletConfigKinds) delete config[kind][id];
10328
+ if (sources[id]) shadows[id] = [...shadows[id] ?? [], sources[id]];
10329
+ delete sources[id];
10330
+ }
10331
+ function formatErrorMessage(error) {
10332
+ return error instanceof Error ? error.message : String(error);
10333
+ }
10334
+ function envProjectConfigPath(env) {
10335
+ return env.CAPLETS_PROJECT_CONFIG?.trim() || resolveProjectConfigPath();
10336
+ }
10337
+ function envProjectCapletsRoot(env) {
10338
+ const projectConfigPath = env.CAPLETS_PROJECT_CONFIG?.trim();
10339
+ return projectConfigPath ? dirname(projectConfigPath) : resolveProjectCapletsRoot();
10340
+ }
10341
+ function mergeRemoteAndLocalRows(remoteRows, localOverlay, options) {
10342
+ const rows = /* @__PURE__ */ new Map();
10343
+ for (const row of remoteRows) rows.set(row.server, {
10344
+ ...row,
10345
+ source: "remote"
10346
+ });
10347
+ if (!localOverlay) return [...rows.values()].filter((row) => options.includeDisabled || !row.disabled).sort((left, right) => left.server.localeCompare(right.server));
10348
+ for (const row of listCaplets(localOverlay, { includeDisabled: true })) {
10349
+ if (rows.get(row.server)) {
10350
+ if (row.disabled) continue;
10351
+ options.writeErr(`Warning: ${formatOverlaySource(row.source)} Caplet ${row.server} shadows remote Caplet\n`);
10352
+ }
10353
+ rows.set(row.server, row);
10354
+ }
10355
+ return [...rows.values()].filter((row) => options.includeDisabled || !row.disabled).sort((left, right) => left.server.localeCompare(right.server));
10356
+ }
10357
+ function formatOverlaySource(kind) {
10358
+ if (kind.startsWith("project")) return "project";
10359
+ if (kind.startsWith("global")) return "global";
10360
+ return kind;
10361
+ }
10362
+ function hasEnabledCaplet(config, id) {
10363
+ const caplet = config.mcpServers[id] ?? config.openapiEndpoints[id] ?? config.graphqlEndpoints[id] ?? config.httpApis[id] ?? config.cliTools[id] ?? config.capletSets[id];
10364
+ return Boolean(caplet && !caplet.disabled);
10365
+ }
10366
+ async function executeLocalOperation(caplet, request, io, config) {
10105
10367
  const configPath = envConfigPath(io.env ?? process.env);
10106
10368
  const engine = new CapletsEngine({
10107
10369
  ...configPath ? { configPath } : {},
10370
+ projectConfigPath: envProjectConfigPath(io.env ?? process.env),
10108
10371
  ...io.authDir ? { authDir: io.authDir } : {},
10109
10372
  watch: false,
10110
- writeErr: io.writeErr
10373
+ writeErr: io.writeErr,
10374
+ ...config ? { configLoader: () => config } : {}
10111
10375
  });
10112
10376
  try {
10113
10377
  const result = await engine.execute(caplet, request);
@@ -10462,8 +10726,8 @@ function schemaSummary(schema) {
10462
10726
  required.length > 0 ? `required ${required.join(", ")}` : "no required fields"
10463
10727
  ].filter((part) => Boolean(part)).join("; ");
10464
10728
  }
10465
- function addDestinationRoot(options, configPath) {
10466
- return options.global ? resolveCapletsRoot(resolveConfigPath(configPath)) : resolveProjectCapletsRoot();
10729
+ function addDestinationRoot(target, configPath, env) {
10730
+ return target === "global" ? resolveCapletsRoot(resolveConfigPath(configPath)) : envProjectCapletsRoot(env);
10467
10731
  }
10468
10732
  function writeAddResult(writeOut, label, result) {
10469
10733
  if (result.path) {