@cydm/pie 2.5.1 → 2.6.0

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.
Files changed (26) hide show
  1. package/dist/builtin/extensions/ask-user/index.js +3 -3
  2. package/dist/builtin/extensions/computer-use/index.js +17 -2
  3. package/dist/builtin/extensions/computer-use/prebuilt/macos/arm64/pie-computer-use +0 -0
  4. package/dist/builtin/extensions/computer-use/prebuilt/macos/universal/pie-computer-use.app/Contents/MacOS/pie-computer-use +0 -0
  5. package/dist/builtin/extensions/computer-use/prebuilt/macos/x64/pie-computer-use +0 -0
  6. package/dist/builtin/extensions/computer-use/scripts/setup-helper.mjs +90 -9
  7. package/dist/builtin/extensions/mcp-adapter/index.js +135 -27
  8. package/dist/builtin/extensions/plan-mode/index.js +3 -3
  9. package/dist/builtin/extensions/subagent/index.js +8 -5
  10. package/dist/builtin/extensions/todo/index.js +3 -3
  11. package/dist/builtin/skills/chrome-devtools-axi/chrome-devtools-axi-bridge.js +199 -40
  12. package/dist/builtin/skills/chrome-devtools-axi/chrome-devtools-axi-cli.js +5 -2
  13. package/dist/builtin/skills/chrome-devtools-axi/chrome-devtools-axi-runtime.js +1 -1
  14. package/dist/builtin/skills/chrome-devtools-axi/{cli-P4VG6ZZG.js → cli-GB37NZHQ.js} +78 -29
  15. package/dist/builtin/skills/tui-use/SKILL.md +44 -0
  16. package/dist/builtin/skills/tui-use/tui-use-cli.cjs +40 -16
  17. package/dist/builtin/skills/tui-use/tui-use-daemon.cjs +7 -1
  18. package/dist/chunks/{chunk-REP6QANY.js → chunk-AZ336HKF.js} +405 -70
  19. package/dist/chunks/{chunk-N2MK46AE.js → chunk-G6KCJA6B.js} +7 -2
  20. package/dist/chunks/{chunk-YRXXRLMQ.js → chunk-O2DKMLNX.js} +152 -8
  21. package/dist/chunks/{chunk-ZKHMNEXL.js → chunk-Y4CYXJR7.js} +27 -2
  22. package/dist/chunks/src-VCWCE7YV.js +20 -0
  23. package/dist/chunks/{test-stream-OD3B57AS.js → test-stream-GOSEWMJ3.js} +1 -1
  24. package/dist/cli.js +67 -17
  25. package/package.json +2 -2
  26. package/dist/chunks/src-SXUQ7OY6.js +0 -14
@@ -16019,6 +16019,9 @@ var Protocol = class {
16019
16019
  this.setRequestHandler(GetTaskPayloadRequestSchema, async (request, extra) => {
16020
16020
  const handleTaskResult = async () => {
16021
16021
  const taskId = request.params.taskId;
16022
+ if (!await this._taskStore.getTask(taskId, extra.sessionId)) {
16023
+ throw new McpError(ErrorCode.InvalidParams, `Task not found: ${taskId}`);
16024
+ }
16022
16025
  if (this._taskMessageQueue) {
16023
16026
  let queuedMessage;
16024
16027
  while (queuedMessage = await this._taskMessageQueue.dequeue(taskId, extra.sessionId)) {
@@ -16049,12 +16052,12 @@ var Protocol = class {
16049
16052
  throw new McpError(ErrorCode.InvalidParams, `Task not found: ${taskId}`);
16050
16053
  }
16051
16054
  if (!isTerminal(task.status)) {
16052
- await this._waitForTaskUpdate(taskId, extra.signal);
16055
+ await this._waitForTaskUpdate(taskId, extra.signal, extra.sessionId);
16053
16056
  return await handleTaskResult();
16054
16057
  }
16055
16058
  if (isTerminal(task.status)) {
16056
16059
  const result = await this._taskStore.getTaskResult(taskId, extra.sessionId);
16057
- this._clearTaskQueue(taskId);
16060
+ this._clearTaskQueue(taskId, extra.sessionId);
16058
16061
  return {
16059
16062
  ...result,
16060
16063
  _meta: {
@@ -16091,7 +16094,7 @@ var Protocol = class {
16091
16094
  throw new McpError(ErrorCode.InvalidParams, `Cannot cancel task in terminal status: ${task.status}`);
16092
16095
  }
16093
16096
  await this._taskStore.updateTaskStatus(request.params.taskId, "cancelled", "Client cancelled task execution.", extra.sessionId);
16094
- this._clearTaskQueue(request.params.taskId);
16097
+ this._clearTaskQueue(request.params.taskId, extra.sessionId);
16095
16098
  const cancelledTask = await this._taskStore.getTask(request.params.taskId, extra.sessionId);
16096
16099
  if (!cancelledTask) {
16097
16100
  throw new McpError(ErrorCode.InvalidParams, `Task not found after cancellation: ${request.params.taskId}`);
@@ -16219,6 +16222,19 @@ var Protocol = class {
16219
16222
  const handler = this._requestHandlers.get(request.method) ?? this.fallbackRequestHandler;
16220
16223
  const capturedTransport = this._transport;
16221
16224
  const relatedTaskId = request.params?._meta?.[RELATED_TASK_META_KEY]?.taskId;
16225
+ const sessionId = capturedTransport?.sessionId;
16226
+ const store = this._taskStore;
16227
+ let relatedTaskFound = true;
16228
+ let relatedTaskLookup;
16229
+ if (relatedTaskId && store && this._taskMessageQueue && sessionId !== void 0) {
16230
+ relatedTaskFound = false;
16231
+ relatedTaskLookup = (async () => {
16232
+ if (!await store.getTask(relatedTaskId, sessionId)) {
16233
+ throw new McpError(ErrorCode.InvalidParams, `Task not found: ${relatedTaskId}`);
16234
+ }
16235
+ relatedTaskFound = true;
16236
+ })();
16237
+ }
16222
16238
  if (handler === void 0) {
16223
16239
  const errorResponse = {
16224
16240
  jsonrpc: "2.0",
@@ -16228,7 +16244,10 @@ var Protocol = class {
16228
16244
  message: "Method not found"
16229
16245
  }
16230
16246
  };
16231
- if (relatedTaskId && this._taskMessageQueue) {
16247
+ if (relatedTaskId && relatedTaskLookup) {
16248
+ const queuedError = { type: "error", message: errorResponse, timestamp: Date.now() };
16249
+ relatedTaskLookup.then(() => this._enqueueTaskMessage(relatedTaskId, queuedError, sessionId), () => capturedTransport?.send(errorResponse)).catch((error2) => this._onerror(new Error(`Failed to send an error response: ${error2}`)));
16250
+ } else if (relatedTaskId && this._taskMessageQueue) {
16232
16251
  this._enqueueTaskMessage(relatedTaskId, {
16233
16252
  type: "error",
16234
16253
  message: errorResponse,
@@ -16279,7 +16298,10 @@ var Protocol = class {
16279
16298
  closeSSEStream: extra?.closeSSEStream,
16280
16299
  closeStandaloneSSEStream: extra?.closeStandaloneSSEStream
16281
16300
  };
16282
- Promise.resolve().then(() => {
16301
+ (relatedTaskLookup ?? Promise.resolve()).then(() => {
16302
+ if (relatedTaskLookup && abortController.signal.aborted) {
16303
+ throw new McpError(ErrorCode.ConnectionClosed, "Request was cancelled");
16304
+ }
16283
16305
  if (taskCreationParams) {
16284
16306
  this.assertTaskHandlerCapability(request.method);
16285
16307
  }
@@ -16314,7 +16336,7 @@ var Protocol = class {
16314
16336
  ...error2["data"] !== void 0 && { data: error2["data"] }
16315
16337
  }
16316
16338
  };
16317
- if (relatedTaskId && this._taskMessageQueue) {
16339
+ if (relatedTaskId && this._taskMessageQueue && relatedTaskFound) {
16318
16340
  await this._enqueueTaskMessage(relatedTaskId, {
16319
16341
  type: "error",
16320
16342
  message: errorResponse,
@@ -16794,7 +16816,7 @@ var Protocol = class {
16794
16816
  throw new Error("Cannot enqueue task message: taskStore and taskMessageQueue are not configured");
16795
16817
  }
16796
16818
  const maxQueueSize = this._options?.maxTaskQueueSize;
16797
- await this._taskMessageQueue.enqueue(taskId, message, sessionId, maxQueueSize);
16819
+ await this._taskMessageQueue.enqueue(taskId, message, sessionId ?? this._transport?.sessionId, maxQueueSize);
16798
16820
  }
16799
16821
  /**
16800
16822
  * Clears the message queue for a task and rejects any pending request resolvers.
@@ -16823,12 +16845,13 @@ var Protocol = class {
16823
16845
  * Uses polling to check for updates at the task's configured poll interval.
16824
16846
  * @param taskId The task ID to wait for
16825
16847
  * @param signal Abort signal to cancel the wait
16848
+ * @param sessionId Session of the request that waits, passed to the task store
16826
16849
  * @returns Promise that resolves when an update occurs or rejects if aborted
16827
16850
  */
16828
- async _waitForTaskUpdate(taskId, signal) {
16851
+ async _waitForTaskUpdate(taskId, signal, sessionId) {
16829
16852
  let interval = this._options?.defaultTaskPollInterval ?? 1e3;
16830
16853
  try {
16831
- const task = await this._taskStore?.getTask(taskId);
16854
+ const task = await this._taskStore?.getTask(taskId, sessionId);
16832
16855
  if (task?.pollInterval) {
16833
16856
  interval = task.pollInterval;
16834
16857
  }
@@ -17956,6 +17979,68 @@ function createFetchWithInit(baseFetch = fetch, baseInit) {
17956
17979
  return baseFetch(url2, mergedInit);
17957
17980
  };
17958
17981
  }
17982
+ var MAX_REDIRECTS = 5;
17983
+ var REDIRECT_STATUSES = [301, 302, 303, 307, 308];
17984
+ function isWithinOrigin(from, to) {
17985
+ if (from.protocol === to.protocol && from.hostname === to.hostname && from.port === to.port) {
17986
+ return true;
17987
+ }
17988
+ return from.hostname === to.hostname && from.protocol === "http:" && from.port === "" && to.protocol === "https:" && to.port === "";
17989
+ }
17990
+ function redirectTarget(response, requestUrl) {
17991
+ const location = REDIRECT_STATUSES.includes(response.status) ? response.headers.get("location") : null;
17992
+ try {
17993
+ return location ? new URL(location, requestUrl) : void 0;
17994
+ } catch {
17995
+ return void 0;
17996
+ }
17997
+ }
17998
+ function followWithinOrigin(baseFetch, url2, init, response, followed = 0) {
17999
+ const target = redirectTarget(response, url2);
18000
+ const keepsMethod = response.status === 307 || response.status === 308 || (init?.method ?? "GET").toUpperCase() === "GET";
18001
+ if (!target || followed === MAX_REDIRECTS || !keepsMethod) {
18002
+ return void 0;
18003
+ }
18004
+ const from = new URL(url2);
18005
+ const addsUserinfo = (target.username || target.password) && (target.username !== from.username || target.password !== from.password);
18006
+ if (addsUserinfo || !isWithinOrigin(from, target)) {
18007
+ return void 0;
18008
+ }
18009
+ return Promise.resolve(response.body?.cancel()).then(() => baseFetch(target, { ...init, redirect: "manual" })).then((next) => followWithinOrigin(baseFetch, target, init, next, followed + 1) ?? next);
18010
+ }
18011
+ var followingFetches = /* @__PURE__ */ new WeakSet();
18012
+ function fetchLeavingRedirects(baseFetch) {
18013
+ const following = (url2, init) => (baseFetch ?? fetch)(url2, init);
18014
+ followingFetches.add(following);
18015
+ return following;
18016
+ }
18017
+ function fetchWithinOrigin(baseFetch = fetch) {
18018
+ if (followingFetches.has(baseFetch)) {
18019
+ return baseFetch;
18020
+ }
18021
+ return (url2, init) => {
18022
+ if (init?.redirect === "error" || init?.redirect === "manual") {
18023
+ return baseFetch(url2, init);
18024
+ }
18025
+ return Promise.resolve(baseFetch(url2, { ...init, redirect: "manual" })).then((response) => followWithinOrigin(baseFetch, url2, init, response) ?? response);
18026
+ };
18027
+ }
18028
+ function unfollowedRedirect(response, requestUrl) {
18029
+ if (response.type === "opaqueredirect") {
18030
+ return "Redirect not followed: this runtime does not expose the redirect target";
18031
+ }
18032
+ const from = response.url || requestUrl;
18033
+ const target = redirectTarget(response, from);
18034
+ if (!target) {
18035
+ return void 0;
18036
+ }
18037
+ target.username = target.password = target.search = target.hash = "";
18038
+ if (target.protocol === "http:" && new URL(from).protocol === "https:") {
18039
+ target.protocol = "https:";
18040
+ return `Redirect to plain http not followed; try ${target.href} instead`;
18041
+ }
18042
+ return `Redirect to ${target.href} not followed`;
18043
+ }
17959
18044
 
17960
18045
  // ../../node_modules/pkce-challenge/dist/index.node.js
17961
18046
  var crypto;
@@ -18102,7 +18187,12 @@ var OAuthTokensSchema = object2({
18102
18187
  token_type: string2(),
18103
18188
  expires_in: coerce_exports.number().optional(),
18104
18189
  scope: string2().optional(),
18105
- refresh_token: string2().optional()
18190
+ refresh_token: string2().optional(),
18191
+ /**
18192
+ * Not part of the wire format: the authorization server this value was obtained from, added by
18193
+ * the client's `auth()` before it is stored and compared when it is read back.
18194
+ */
18195
+ issuer: string2().optional().catch(void 0)
18106
18196
  }).strip();
18107
18197
  var OAuthErrorResponseSchema = object2({
18108
18198
  error: string2(),
@@ -18132,7 +18222,12 @@ var OAuthClientInformationSchema = object2({
18132
18222
  client_id: string2(),
18133
18223
  client_secret: string2().optional(),
18134
18224
  client_id_issued_at: number2().optional(),
18135
- client_secret_expires_at: number2().optional()
18225
+ client_secret_expires_at: number2().optional(),
18226
+ /**
18227
+ * Not part of the wire format: the authorization server this value was obtained from, added by
18228
+ * the client's `auth()` before it is stored and compared when it is read back.
18229
+ */
18230
+ issuer: string2().optional().catch(void 0)
18136
18231
  }).strip();
18137
18232
  var OAuthClientInformationFullSchema = OAuthClientMetadataSchema.merge(OAuthClientInformationSchema);
18138
18233
  var OAuthClientRegistrationErrorSchema = object2({
@@ -18330,10 +18425,31 @@ async function parseErrorResponse(input) {
18330
18425
  const errorClass = OAUTH_ERRORS[error2] || ServerError;
18331
18426
  return new errorClass(error_description || "", error_uri);
18332
18427
  } catch (error2) {
18333
- const errorMessage = `${statusCode ? `HTTP ${statusCode}: ` : ""}Invalid OAuth error response: ${error2}. Raw body: ${body}`;
18428
+ const redirect = input instanceof Response ? unfollowedRedirect(input, input.url) : void 0;
18429
+ const errorMessage = `${statusCode ? `HTTP ${statusCode}: ` : ""}${redirect ?? `Invalid OAuth error response: ${error2}. Raw body: ${body}`}`;
18334
18430
  return new ServerError(errorMessage);
18335
18431
  }
18336
18432
  }
18433
+ function issuersMatch(a, b) {
18434
+ let [x, y] = [a, b];
18435
+ try {
18436
+ [x, y] = [new URL(a).href, new URL(b).href];
18437
+ } catch {
18438
+ }
18439
+ return x === y || x.endsWith("/") && x.slice(0, -1) === y || y.endsWith("/") && y.slice(0, -1) === x;
18440
+ }
18441
+ function discardIfIssuerMismatch(stored, issuer) {
18442
+ if (!stored)
18443
+ return void 0;
18444
+ if (typeof stored.issuer !== "string")
18445
+ return stored.issuer == null ? stored : { ...stored, issuer: void 0 };
18446
+ return issuersMatch(stored.issuer, issuer) ? stored : void 0;
18447
+ }
18448
+ var TokenResponseSchema = OAuthTokensSchema.omit({ issuer: true });
18449
+ var RegistrationResponseSchema = OAuthClientInformationFullSchema.omit({ issuer: true });
18450
+ function boundElsewhereError(stored, issuer) {
18451
+ return new Error(`OAuth client information is bound to authorization server ${stored.issuer} and is not presented to ${issuer}. Clear the stored client information, or correct \`expectedIssuer\`, if the authorization server has moved.`);
18452
+ }
18337
18453
  async function auth(provider, options) {
18338
18454
  try {
18339
18455
  return await authInternal(provider, options);
@@ -18387,10 +18503,24 @@ async function authInternal(provider, { serverUrl, authorizationCode, scope, res
18387
18503
  authorizationServerMetadata: metadata
18388
18504
  });
18389
18505
  }
18506
+ const issuer = String(authorizationServerUrl);
18390
18507
  const selectedResource = await selectResourceURL(serverUrl, provider, resourceMetadata);
18391
18508
  const resource = selectedResource && resourceMetadata && !provider.validateResourceURL ? resourceMetadata.resource : selectedResource;
18392
18509
  const resolvedScope = scope || resourceMetadata?.scopes_supported?.join(" ") || provider.clientMetadata.scope;
18393
- let clientInformation = await Promise.resolve(provider.clientInformation());
18510
+ const storedClientInformation = await Promise.resolve(provider.clientInformation());
18511
+ let clientInformation = discardIfIssuerMismatch(storedClientInformation, issuer);
18512
+ const canRegisterAgain = provider.saveClientInformation !== void 0 && !!provider.redirectUrl;
18513
+ if (storedClientInformation && !clientInformation && !canRegisterAgain) {
18514
+ throw boundElsewhereError(storedClientInformation, issuer);
18515
+ }
18516
+ const unstampedClientInformation = clientInformation?.issuer == null ? clientInformation : void 0;
18517
+ const bindClientInformation = async () => {
18518
+ try {
18519
+ if (unstampedClientInformation)
18520
+ await provider.saveClientInformation?.({ ...unstampedClientInformation, issuer });
18521
+ } catch {
18522
+ }
18523
+ };
18394
18524
  if (!clientInformation) {
18395
18525
  if (authorizationCode !== void 0) {
18396
18526
  throw new Error("Existing OAuth client information is required when exchanging an authorization code");
@@ -18402,9 +18532,7 @@ async function authInternal(provider, { serverUrl, authorizationCode, scope, res
18402
18532
  }
18403
18533
  const shouldUseUrlBasedClientId = supportsUrlBasedClientId && clientMetadataUrl;
18404
18534
  if (shouldUseUrlBasedClientId) {
18405
- clientInformation = {
18406
- client_id: clientMetadataUrl
18407
- };
18535
+ clientInformation = { client_id: clientMetadataUrl, issuer };
18408
18536
  await provider.saveClientInformation?.(clientInformation);
18409
18537
  } else {
18410
18538
  if (!provider.saveClientInformation) {
@@ -18416,8 +18544,8 @@ async function authInternal(provider, { serverUrl, authorizationCode, scope, res
18416
18544
  scope: resolvedScope,
18417
18545
  fetchFn
18418
18546
  });
18419
- await provider.saveClientInformation(fullInformation);
18420
- clientInformation = fullInformation;
18547
+ clientInformation = { ...fullInformation, issuer };
18548
+ await provider.saveClientInformation(clientInformation);
18421
18549
  }
18422
18550
  }
18423
18551
  const nonInteractiveFlow = !provider.redirectUrl;
@@ -18428,10 +18556,14 @@ async function authInternal(provider, { serverUrl, authorizationCode, scope, res
18428
18556
  authorizationCode,
18429
18557
  fetchFn
18430
18558
  });
18431
- await provider.saveTokens(tokens2);
18559
+ await bindClientInformation();
18560
+ await provider.saveTokens({ ...tokens2, issuer });
18432
18561
  return "AUTHORIZED";
18433
18562
  }
18434
- const tokens = await provider.tokens();
18563
+ const tokens = discardIfIssuerMismatch(await provider.tokens(), issuer);
18564
+ if (tokens?.refresh_token && tokens.issuer == null) {
18565
+ console.warn("[mcp-sdk] stored OAuth tokens have no 'issuer' property (saved by an earlier version, or by a provider that does not keep it) and are used as-is; make sure your OAuthClientProvider stores what saveTokens() and saveClientInformation() receive unchanged.");
18566
+ }
18435
18567
  if (tokens?.refresh_token) {
18436
18568
  try {
18437
18569
  const newTokens = await refreshAuthorization(authorizationServerUrl, {
@@ -18442,7 +18574,8 @@ async function authInternal(provider, { serverUrl, authorizationCode, scope, res
18442
18574
  addClientAuthentication: provider.addClientAuthentication,
18443
18575
  fetchFn
18444
18576
  });
18445
- await provider.saveTokens(newTokens);
18577
+ await bindClientInformation();
18578
+ await provider.saveTokens({ ...newTokens, issuer });
18446
18579
  return "AUTHORIZED";
18447
18580
  } catch (error2) {
18448
18581
  if (!(error2 instanceof OAuthError) || error2 instanceof ServerError) {
@@ -18541,7 +18674,7 @@ async function discoverOAuthProtectedResourceMetadata(serverUrl, opts, fetchFn =
18541
18674
  }
18542
18675
  async function fetchWithCorsRetry(url2, headers, fetchFn = fetch) {
18543
18676
  try {
18544
- return await fetchFn(url2, { headers });
18677
+ return await fetchWithinOrigin(fetchFn)(url2, { headers });
18545
18678
  } catch (error2) {
18546
18679
  if (error2 instanceof TypeError) {
18547
18680
  if (headers) {
@@ -18566,7 +18699,7 @@ async function tryMetadataDiscovery(url2, protocolVersion, fetchFn = fetch) {
18566
18699
  return await fetchWithCorsRetry(url2, headers, fetchFn);
18567
18700
  }
18568
18701
  function shouldAttemptFallback(response, pathname) {
18569
- return !response || response.status >= 400 && response.status < 500 && pathname !== "/";
18702
+ return !response || !response.ok && response.status < 500 && pathname !== "/";
18570
18703
  }
18571
18704
  async function discoverMetadataWithFallback(serverUrl, wellKnownType, fetchFn, opts) {
18572
18705
  const issuer = new URL(serverUrl);
@@ -18632,7 +18765,7 @@ async function discoverAuthorizationServerMetadata(authorizationServerUrl, { fet
18632
18765
  }
18633
18766
  if (!response.ok) {
18634
18767
  await response.body?.cancel();
18635
- if (response.status >= 400 && response.status < 500) {
18768
+ if (response.status < 500) {
18636
18769
  continue;
18637
18770
  }
18638
18771
  throw new Error(`HTTP ${response.status} trying to load ${type === "oauth" ? "OAuth" : "OpenID provider"} metadata from ${endpointUrl}`);
@@ -18727,7 +18860,7 @@ async function executeTokenRequest(authorizationServerUrl, { metadata, tokenRequ
18727
18860
  const authMethod = selectClientAuthMethod(clientInformation, supportedMethods);
18728
18861
  applyClientAuthentication(authMethod, clientInformation, headers, tokenRequestParams);
18729
18862
  }
18730
- const response = await (fetchFn ?? fetch)(tokenUrl, {
18863
+ const response = await fetchWithinOrigin(fetchFn ?? fetch)(tokenUrl, {
18731
18864
  method: "POST",
18732
18865
  headers,
18733
18866
  body: tokenRequestParams
@@ -18735,7 +18868,7 @@ async function executeTokenRequest(authorizationServerUrl, { metadata, tokenRequ
18735
18868
  if (!response.ok) {
18736
18869
  throw await parseErrorResponse(response);
18737
18870
  }
18738
- return OAuthTokensSchema.parse(await response.json());
18871
+ return TokenResponseSchema.parse(await response.json());
18739
18872
  }
18740
18873
  async function refreshAuthorization(authorizationServerUrl, { metadata, clientInformation, refreshToken, resource, addClientAuthentication, fetchFn }) {
18741
18874
  const tokenRequestParams = new URLSearchParams({
@@ -18753,6 +18886,15 @@ async function refreshAuthorization(authorizationServerUrl, { metadata, clientIn
18753
18886
  return { refresh_token: refreshToken, ...tokens };
18754
18887
  }
18755
18888
  async function fetchToken(provider, authorizationServerUrl, { metadata, resource, authorizationCode, fetchFn } = {}) {
18889
+ const readClientInformation = async () => {
18890
+ const storedClientInformation = await provider.clientInformation();
18891
+ const checked = discardIfIssuerMismatch(storedClientInformation, String(authorizationServerUrl));
18892
+ if (storedClientInformation && !checked) {
18893
+ throw boundElsewhereError(storedClientInformation, String(authorizationServerUrl));
18894
+ }
18895
+ return checked;
18896
+ };
18897
+ let clientInformation = await readClientInformation();
18756
18898
  const scope = provider.clientMetadata.scope;
18757
18899
  let tokenRequestParams;
18758
18900
  if (provider.prepareTokenRequest) {
@@ -18768,11 +18910,11 @@ async function fetchToken(provider, authorizationServerUrl, { metadata, resource
18768
18910
  const codeVerifier = await provider.codeVerifier();
18769
18911
  tokenRequestParams = prepareAuthorizationCodeRequest(authorizationCode, codeVerifier, provider.redirectUrl);
18770
18912
  }
18771
- const clientInformation = await provider.clientInformation();
18913
+ clientInformation ?? (clientInformation = await readClientInformation());
18772
18914
  return executeTokenRequest(authorizationServerUrl, {
18773
18915
  metadata,
18774
18916
  tokenRequestParams,
18775
- clientInformation: clientInformation ?? void 0,
18917
+ clientInformation,
18776
18918
  addClientAuthentication: provider.addClientAuthentication,
18777
18919
  resource,
18778
18920
  fetchFn
@@ -18788,7 +18930,7 @@ async function registerClient(authorizationServerUrl, { metadata, clientMetadata
18788
18930
  } else {
18789
18931
  registrationUrl = new URL("/register", authorizationServerUrl);
18790
18932
  }
18791
- const response = await (fetchFn ?? fetch)(registrationUrl, {
18933
+ const response = await fetchWithinOrigin(fetchFn ?? fetch)(registrationUrl, {
18792
18934
  method: "POST",
18793
18935
  headers: {
18794
18936
  "Content-Type": "application/json"
@@ -18801,7 +18943,7 @@ async function registerClient(authorizationServerUrl, { metadata, clientMetadata
18801
18943
  if (!response.ok) {
18802
18944
  throw await parseErrorResponse(response);
18803
18945
  }
18804
- return OAuthClientInformationFullSchema.parse(await response.json());
18946
+ return RegistrationResponseSchema.parse(await response.json());
18805
18947
  }
18806
18948
 
18807
18949
  // ../../node_modules/eventsource-parser/dist/index.js
@@ -19028,9 +19170,19 @@ var StreamableHTTPClientTransport = class {
19028
19170
  this._authProvider = opts?.authProvider;
19029
19171
  this._fetch = opts?.fetch;
19030
19172
  this._fetchWithInit = createFetchWithInit(opts?.fetch, opts?.requestInit);
19173
+ this._followRedirects = opts?.redirectPolicy === "follow";
19174
+ if (this._followRedirects) {
19175
+ this._fetch = fetchLeavingRedirects(this._fetch);
19176
+ this._fetchWithInit = fetchLeavingRedirects(this._fetchWithInit);
19177
+ }
19031
19178
  this._sessionId = opts?.sessionId;
19032
19179
  this._reconnectionOptions = opts?.reconnectionOptions ?? DEFAULT_STREAMABLE_HTTP_RECONNECTION_OPTIONS;
19033
19180
  }
19181
+ /** Error text for a redirect `response` that was not followed, or `undefined` for any other response. */
19182
+ _unfollowedRedirect(response, url2) {
19183
+ const text = unfollowedRedirect(response, url2);
19184
+ return text && !this._followRedirects ? `${text} (redirectPolicy: 'same-origin')` : text;
19185
+ }
19034
19186
  async _authThenStart() {
19035
19187
  if (!this._authProvider) {
19036
19188
  throw new UnauthorizedError("No auth provider");
@@ -19080,11 +19232,13 @@ var StreamableHTTPClientTransport = class {
19080
19232
  if (resumptionToken) {
19081
19233
  headers.set("last-event-id", resumptionToken);
19082
19234
  }
19083
- const response = await (this._fetch ?? fetch)(this._url, {
19084
- method: "GET",
19085
- headers,
19086
- signal: this._abortController?.signal
19087
- });
19235
+ const fetchFn = this._fetch ?? fetch;
19236
+ const init = { method: "GET", headers, signal: this._abortController?.signal };
19237
+ let response = await fetchFn(this._url, this._followRedirects ? init : { ...init, redirect: "manual" });
19238
+ const followed = this._followRedirects ? void 0 : followWithinOrigin(fetchFn, this._url, init, response);
19239
+ if (followed) {
19240
+ response = await followed;
19241
+ }
19088
19242
  if (!response.ok) {
19089
19243
  await response.body?.cancel();
19090
19244
  if (response.status === 401 && this._authProvider) {
@@ -19093,7 +19247,7 @@ var StreamableHTTPClientTransport = class {
19093
19247
  if (response.status === 405) {
19094
19248
  return;
19095
19249
  }
19096
- throw new StreamableHTTPError(response.status, `Failed to open SSE stream: ${response.statusText}`);
19250
+ throw new StreamableHTTPError(response.status, `Failed to open SSE stream: ${this._unfollowedRedirect(response, this._url) ?? response.statusText}`);
19097
19251
  }
19098
19252
  this._handleSseStream(response.body, options, true);
19099
19253
  } catch (error2) {
@@ -19256,7 +19410,7 @@ var StreamableHTTPClientTransport = class {
19256
19410
  body: JSON.stringify(message),
19257
19411
  signal: this._abortController?.signal
19258
19412
  };
19259
- const response = await (this._fetch ?? fetch)(this._url, init);
19413
+ const response = await fetchWithinOrigin(this._fetch ?? fetch)(this._url, init);
19260
19414
  const sessionId = response.headers.get("mcp-session-id");
19261
19415
  if (sessionId) {
19262
19416
  this._sessionId = sessionId;
@@ -19308,7 +19462,7 @@ var StreamableHTTPClientTransport = class {
19308
19462
  return this.send(message);
19309
19463
  }
19310
19464
  }
19311
- throw new StreamableHTTPError(response.status, `Error POSTing to endpoint: ${text}`);
19465
+ throw new StreamableHTTPError(response.status, `Error POSTing to endpoint: ${this._unfollowedRedirect(response, this._url) ?? text}`);
19312
19466
  }
19313
19467
  this._hasCompletedAuthFlow = false;
19314
19468
  this._lastUpscopingHeader = void 0;
@@ -19370,10 +19524,10 @@ var StreamableHTTPClientTransport = class {
19370
19524
  headers,
19371
19525
  signal: this._abortController?.signal
19372
19526
  };
19373
- const response = await (this._fetch ?? fetch)(this._url, init);
19527
+ const response = await fetchWithinOrigin(this._fetch ?? fetch)(this._url, init);
19374
19528
  await response.body?.cancel();
19375
19529
  if (!response.ok && response.status !== 405) {
19376
- throw new StreamableHTTPError(response.status, `Failed to terminate session: ${response.statusText}`);
19530
+ throw new StreamableHTTPError(response.status, `Failed to terminate session: ${this._unfollowedRedirect(response, this._url) ?? response.statusText}`);
19377
19531
  }
19378
19532
  this._sessionId = void 0;
19379
19533
  } catch (error2) {
@@ -19640,6 +19794,11 @@ async function handleBridgeRequest(client, req, res, sessionName, logForbidden,
19640
19794
  writeJson(res, 200, {
19641
19795
  status: "ok",
19642
19796
  session: sessionName,
19797
+ // The bridge's own PID so `stop` can verify that the process named
19798
+ // in a (possibly stale) pid file is really THIS bridge before any
19799
+ // signal is sent — a healthy session on the recorded port alone
19800
+ // must not authorize killing an unrelated reused PID.
19801
+ pid: process.pid,
19643
19802
  busy: client.isBusy?.() ?? false,
19644
19803
  ...droppedSelection ? { pageIdentityChanged: true } : {}
19645
19804
  });
@@ -46,8 +46,11 @@ export function runChromeDevtoolsAxiCli(args = process.argv.slice(2), options =
46
46
  ...process.env,
47
47
  CHROME_DEVTOOLS_AXI_MCP_PATH: process.env.CHROME_DEVTOOLS_AXI_MCP_PATH?.trim() || resolveChromeDevtoolsMcpScript(),
48
48
  // Pie pins chrome-devtools-mcp; its daily background update check
49
- // (network + ~/.cache write + "install @latest" nag) stays off unless
50
- // the environment or caller explicitly provides a value.
49
+ // (network + ~/.cache write + "install @latest" nag) is UNCONDITIONALLY
50
+ // disabled for the packaged CLI: the upstream treats any nonempty
51
+ // value — including "0" or "false" — as "disable", so this env var
52
+ // cannot re-enable the check. To run the check, invoke the vendored
53
+ // cli outside Pie with the variable unset.
51
54
  CHROME_DEVTOOLS_MCP_NO_UPDATE_CHECKS: process.env.CHROME_DEVTOOLS_MCP_NO_UPDATE_CHECKS || "1",
52
55
  ...options.env,
53
56
  },
@@ -21,6 +21,6 @@ function tryFastPath(argv, options) {
21
21
 
22
22
  // vendor/chrome-devtools-axi/bin/chrome-devtools-axi.ts
23
23
  if (!tryFastPath(process.argv.slice(2), { version: VERSION })) {
24
- const { main } = await import("./cli-P4VG6ZZG.js");
24
+ const { main } = await import("./cli-GB37NZHQ.js");
25
25
  await main(process.argv.slice(2));
26
26
  }