@higgsfield/video-editor-mcp 1.0.3 → 1.0.5

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/server.mjs CHANGED
@@ -25742,11 +25742,11 @@ var isJSONRPCNotification = (value) => JSONRPCNotificationSchema.safeParse(value
25742
25742
  var isJSONRPCResultResponse = (value) => JSONRPCResultResponseSchema.safeParse(value).success;
25743
25743
  var isJSONRPCErrorResponse = (value) => JSONRPCErrorResponseSchema.safeParse(value).success;
25744
25744
  var isInputRequiredResult = (value) => typeof value === "object" && value !== null && !Array.isArray(value) && value.resultType === "input_required";
25745
- function assertCompleteRequestPrompt(request2) {
25746
- if (request2.params.ref.type !== "ref/prompt") throw new TypeError(`Expected CompleteRequestPrompt, but got ${request2.params.ref.type}`);
25745
+ function assertCompleteRequestPrompt(request3) {
25746
+ if (request3.params.ref.type !== "ref/prompt") throw new TypeError(`Expected CompleteRequestPrompt, but got ${request3.params.ref.type}`);
25747
25747
  }
25748
- function assertCompleteRequestResourceTemplate(request2) {
25749
- if (request2.params.ref.type !== "ref/resource") throw new TypeError(`Expected CompleteRequestResourceTemplate, but got ${request2.params.ref.type}`);
25748
+ function assertCompleteRequestResourceTemplate(request3) {
25749
+ if (request3.params.ref.type !== "ref/resource") throw new TypeError(`Expected CompleteRequestResourceTemplate, but got ${request3.params.ref.type}`);
25750
25750
  }
25751
25751
  var X_MCP_HEADER_KEY = "x-mcp-header";
25752
25752
  var RFC9110_TOKEN = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
@@ -26778,7 +26778,7 @@ var Protocol = class {
26778
26778
  Promise.resolve().then(() => handler === void 0 ? fallback(notification) : handler(notification, codec2)).catch((error51) => this._onerror(/* @__PURE__ */ new Error(`Uncaught error in notification handler: ${error51}`)));
26779
26779
  }
26780
26780
  _onrequest(rawRequest, extra) {
26781
- const { message: request2, lifted } = liftWireOnlyMaterial(rawRequest, "request");
26781
+ const { message: request3, lifted } = liftWireOnlyMaterial(rawRequest, "request");
26782
26782
  const codec2 = this._negotiatedWireCodec();
26783
26783
  if (extra?.classification === void 0 && this._shouldDropInbound(rawRequest) === "drop") {
26784
26784
  this._onerror(/* @__PURE__ */ new Error(`Dropped inbound request '${rawRequest.method}': not servable on this connection's protocol era`));
@@ -26788,7 +26788,7 @@ var Protocol = class {
26788
26788
  const sendErrorResponse = (code, message, data) => {
26789
26789
  const errorResponse = {
26790
26790
  jsonrpc: "2.0",
26791
- id: request2.id,
26791
+ id: request3.id,
26792
26792
  error: {
26793
26793
  code,
26794
26794
  message,
@@ -26800,7 +26800,7 @@ var Protocol = class {
26800
26800
  if (extra?.classification !== void 0) {
26801
26801
  const classified = classifiedWireEra(extra.classification);
26802
26802
  if (classified !== codec2.era) {
26803
- this._onerror(/* @__PURE__ */ new Error(`Era mismatch on inbound request '${request2.method}': classified as ${classified} but this instance serves ${codec2.era}`));
26803
+ this._onerror(/* @__PURE__ */ new Error(`Era mismatch on inbound request '${request3.method}': classified as ${classified} but this instance serves ${codec2.era}`));
26804
26804
  const requested = extra.classification.revision ?? classified;
26805
26805
  sendErrorResponse(ProtocolErrorCode.UnsupportedProtocolVersion, `Unsupported protocol version: ${requested}`, {
26806
26806
  supported: this._supportedProtocolVersions,
@@ -26809,11 +26809,11 @@ var Protocol = class {
26809
26809
  return;
26810
26810
  }
26811
26811
  }
26812
- if (isSpecRequestMethod(request2.method) && !codec2.hasRequestMethod(request2.method)) {
26812
+ if (isSpecRequestMethod(request3.method) && !codec2.hasRequestMethod(request3.method)) {
26813
26813
  sendErrorResponse(ProtocolErrorCode.MethodNotFound, "Method not found");
26814
26814
  return;
26815
26815
  }
26816
- const handler = this._requestHandlers.get(request2.method) ?? this.fallbackRequestHandler;
26816
+ const handler = this._requestHandlers.get(request3.method) ?? this.fallbackRequestHandler;
26817
26817
  if (handler === void 0) {
26818
26818
  sendErrorResponse(ProtocolErrorCode.MethodNotFound, "Method not found");
26819
26819
  return;
@@ -26825,21 +26825,21 @@ var Protocol = class {
26825
26825
  }
26826
26826
  const sendNotification = (notification, options) => this._notificationViaCodec(this._resolveOutboundCodec(notification.method), notification, {
26827
26827
  ...options,
26828
- relatedRequestId: request2.id
26828
+ relatedRequestId: request3.id
26829
26829
  });
26830
26830
  const sendRequest = (r, resultSchema, options) => this._requestWithSchemaViaCodec(this._resolveOutboundCodec(r.method), r, resultSchema, {
26831
26831
  ...options,
26832
- relatedRequestId: request2.id
26832
+ relatedRequestId: request3.id
26833
26833
  });
26834
26834
  const abortController = new AbortController();
26835
- this._requestHandlerAbortControllers.set(request2.id, abortController);
26835
+ this._requestHandlerAbortControllers.set(request3.id, abortController);
26836
26836
  const partitionedInputResponses = lifted.inputResponses === void 0 ? void 0 : partitionInputResponses(lifted.inputResponses);
26837
26837
  const baseCtx = {
26838
26838
  sessionId: capturedTransport?.sessionId,
26839
26839
  mcpReq: {
26840
- id: request2.id,
26841
- method: request2.method,
26842
- _meta: request2.params?._meta,
26840
+ id: request3.id,
26841
+ method: request3.method,
26842
+ _meta: request3.params?._meta,
26843
26843
  ...lifted.envelope !== void 0 && { envelope: lifted.envelope },
26844
26844
  ...partitionedInputResponses !== void 0 && { inputResponses: partitionedInputResponses.accepted },
26845
26845
  ...partitionedInputResponses !== void 0 && partitionedInputResponses.droppedKeys.length > 0 && { droppedInputResponseKeys: partitionedInputResponses.droppedKeys },
@@ -26858,20 +26858,20 @@ var Protocol = class {
26858
26858
  http: extra?.authInfo ? { authInfo: extra.authInfo } : void 0
26859
26859
  };
26860
26860
  const ctx = this.buildContext(baseCtx, extra);
26861
- Promise.resolve().then(() => handler(request2, ctx)).then(async (result) => {
26861
+ Promise.resolve().then(() => handler(request3, ctx)).then(async (result) => {
26862
26862
  if (abortController.signal.aborted) return;
26863
26863
  let encoded;
26864
26864
  try {
26865
- encoded = codec2.encodeResult(request2.method, result, this._outboundServerInfo());
26865
+ encoded = codec2.encodeResult(request3.method, result, this._outboundServerInfo());
26866
26866
  } catch (error51) {
26867
- this._onerror(/* @__PURE__ */ new Error(`Failed to encode result for ${request2.method}: ${error51}`));
26867
+ this._onerror(/* @__PURE__ */ new Error(`Failed to encode result for ${request3.method}: ${error51}`));
26868
26868
  sendErrorResponse(ProtocolErrorCode.InternalError, "Internal error");
26869
26869
  return;
26870
26870
  }
26871
26871
  const response = {
26872
26872
  result: encoded,
26873
26873
  jsonrpc: "2.0",
26874
- id: request2.id
26874
+ id: request3.id
26875
26875
  };
26876
26876
  await capturedTransport?.send(response);
26877
26877
  }, async (error51) => {
@@ -26879,7 +26879,7 @@ var Protocol = class {
26879
26879
  const thrownCode = Number.isSafeInteger(error51["code"]) ? error51["code"] : ProtocolErrorCode.InternalError;
26880
26880
  const errorResponse = {
26881
26881
  jsonrpc: "2.0",
26882
- id: request2.id,
26882
+ id: request3.id,
26883
26883
  error: {
26884
26884
  code: codec2.encodeErrorCode(thrownCode),
26885
26885
  message: error51.message ?? "Internal error",
@@ -26888,7 +26888,7 @@ var Protocol = class {
26888
26888
  };
26889
26889
  await capturedTransport?.send(errorResponse);
26890
26890
  }).catch((error51) => this._onerror(/* @__PURE__ */ new Error(`Failed to send response: ${error51}`))).finally(() => {
26891
- if (this._requestHandlerAbortControllers.get(request2.id) === abortController) this._requestHandlerAbortControllers.delete(request2.id);
26891
+ if (this._requestHandlerAbortControllers.get(request3.id) === abortController) this._requestHandlerAbortControllers.delete(request3.id);
26892
26892
  });
26893
26893
  }
26894
26894
  _onprogress(notification) {
@@ -26940,13 +26940,13 @@ var Protocol = class {
26940
26940
  async close() {
26941
26941
  await this._transport?.close();
26942
26942
  }
26943
- request(request2, schemaOrOptions, maybeOptions) {
26944
- const codec2 = this._resolveOutboundCodec(request2.method);
26945
- this._assertOutboundRequestInEra(codec2, request2.method);
26946
- if (isStandardSchema(schemaOrOptions)) return this._requestWithSchemaViaCodec(codec2, request2, schemaOrOptions, maybeOptions);
26947
- const validate = codecResultValidator(codec2, request2.method);
26948
- if (validate === void 0) throw new TypeError(`'${request2.method}' is not a spec method; pass a result schema as the second argument to request().`);
26949
- return this._requestWithSchemaViaCodec(codec2, request2, validate, schemaOrOptions);
26943
+ request(request3, schemaOrOptions, maybeOptions) {
26944
+ const codec2 = this._resolveOutboundCodec(request3.method);
26945
+ this._assertOutboundRequestInEra(codec2, request3.method);
26946
+ if (isStandardSchema(schemaOrOptions)) return this._requestWithSchemaViaCodec(codec2, request3, schemaOrOptions, maybeOptions);
26947
+ const validate = codecResultValidator(codec2, request3.method);
26948
+ if (validate === void 0) throw new TypeError(`'${request3.method}' is not a spec method; pass a result schema as the second argument to request().`);
26949
+ return this._requestWithSchemaViaCodec(codec2, request3, validate, schemaOrOptions);
26950
26950
  }
26951
26951
  /**
26952
26952
  * The wire codec for this instance's negotiated era — the phase-2 truth:
@@ -27005,17 +27005,17 @@ var Protocol = class {
27005
27005
  * explicit compatibility schemas. Spec methods are still era-gated here:
27006
27006
  * an explicit schema never smuggles a deleted method onto the wire.
27007
27007
  */
27008
- _requestWithSchema(request2, resultSchema, options) {
27009
- const codec2 = this._resolveOutboundCodec(request2.method);
27010
- this._assertOutboundRequestInEra(codec2, request2.method);
27011
- return this._requestWithSchemaViaCodec(codec2, request2, resultSchema, options);
27008
+ _requestWithSchema(request3, resultSchema, options) {
27009
+ const codec2 = this._resolveOutboundCodec(request3.method);
27010
+ this._assertOutboundRequestInEra(codec2, request3.method);
27011
+ return this._requestWithSchemaViaCodec(codec2, request3, resultSchema, options);
27012
27012
  }
27013
27013
  /**
27014
27014
  * The request funnel proper, keyed by the resolved era codec: the codec
27015
27015
  * owns result decoding (raw-first `resultType` discrimination — V-1 —
27016
27016
  * and the era's lift posture) before the schema validation step.
27017
27017
  */
27018
- _requestWithSchemaViaCodec(codec2, request2, resultSchema, options) {
27018
+ _requestWithSchemaViaCodec(codec2, request3, resultSchema, options) {
27019
27019
  const { relatedRequestId, resumptionToken, onresumptiontoken, headers } = options ?? {};
27020
27020
  const flowStartedAt = Date.now();
27021
27021
  let onAbort;
@@ -27029,7 +27029,7 @@ var Protocol = class {
27029
27029
  return;
27030
27030
  }
27031
27031
  if (this._options?.enforceStrictCapabilities === true) try {
27032
- this.assertCapabilityForMethod(request2.method);
27032
+ this.assertCapabilityForMethod(request3.method);
27033
27033
  } catch (error51) {
27034
27034
  earlyReject(error51);
27035
27035
  return;
@@ -27042,16 +27042,16 @@ var Protocol = class {
27042
27042
  const messageId = this._requestMessageId++;
27043
27043
  cleanupMessageId = messageId;
27044
27044
  const jsonrpcRequest = {
27045
- ...request2,
27045
+ ...request3,
27046
27046
  jsonrpc: "2.0",
27047
27047
  id: messageId
27048
27048
  };
27049
27049
  if (options?.onprogress) {
27050
27050
  this._progressHandlers.set(messageId, options.onprogress);
27051
27051
  jsonrpcRequest.params = {
27052
- ...request2.params,
27052
+ ...request3.params,
27053
27053
  _meta: {
27054
- ...request2.params?._meta,
27054
+ ...request3.params?._meta,
27055
27055
  progressToken: messageId
27056
27056
  }
27057
27057
  };
@@ -27082,7 +27082,7 @@ var Protocol = class {
27082
27082
  if (response instanceof Error) return reject(response);
27083
27083
  let decoded;
27084
27084
  try {
27085
- decoded = codec2.decodeResult(request2.method, response.result);
27085
+ decoded = codec2.decodeResult(request3.method, response.result);
27086
27086
  } catch (error51) {
27087
27087
  return reject(error51 instanceof Error ? error51 : new Error(String(error51)));
27088
27088
  }
@@ -27091,12 +27091,12 @@ var Protocol = class {
27091
27091
  if (options?.allowInputRequired === true) return resolve3(manualInputRequiredValue(decoded));
27092
27092
  const flow = {
27093
27093
  codec: codec2,
27094
- request: request2,
27094
+ request: request3,
27095
27095
  resultSchema,
27096
27096
  options,
27097
27097
  flowStartedAt,
27098
- retry: (params, legOptions) => this._requestWithSchemaViaCodec(codec2, params === void 0 ? { method: request2.method } : {
27099
- method: request2.method,
27098
+ retry: (params, legOptions) => this._requestWithSchemaViaCodec(codec2, params === void 0 ? { method: request3.method } : {
27099
+ method: request3.method,
27100
27100
  params
27101
27101
  }, resultSchema, legOptions)
27102
27102
  };
@@ -27105,7 +27105,7 @@ var Protocol = class {
27105
27105
  const result = decoded.result;
27106
27106
  validateStandardSchema(resultSchema, result).then((parseResult) => {
27107
27107
  if (parseResult.success) resolve3(parseResult.data);
27108
- else reject(new SdkError(SdkErrorCode.InvalidResult, `Invalid result for ${request2.method}: ${parseResult.error}`));
27108
+ else reject(new SdkError(SdkErrorCode.InvalidResult, `Invalid result for ${request3.method}: ${parseResult.error}`));
27109
27109
  }, reject);
27110
27110
  });
27111
27111
  onAbort = () => cancel(options?.signal?.reason);
@@ -27170,18 +27170,18 @@ var Protocol = class {
27170
27170
  let stored;
27171
27171
  if (typeof schemasOrHandler === "function") {
27172
27172
  if (!isSpecRequestMethod(method)) throw new TypeError(`'${method}' is not a spec request method; pass schemas as the second argument to setRequestHandler().`);
27173
- stored = (request2, ctx) => {
27173
+ stored = (request3, ctx) => {
27174
27174
  const dispatchCodec = this._negotiatedWireCodec();
27175
- let outcome = dispatchCodec.validateRequest(method, request2);
27176
- if (!outcome.ok && outcome.reason === "not-in-era") outcome = dispatchCodec.validateInputRequest(method, request2);
27175
+ let outcome = dispatchCodec.validateRequest(method, request3);
27176
+ if (!outcome.ok && outcome.reason === "not-in-era") outcome = dispatchCodec.validateInputRequest(method, request3);
27177
27177
  if (!outcome.ok) {
27178
27178
  if (outcome.reason === "not-in-era") throw new ProtocolError(ProtocolErrorCode.InternalError, `No wire schema for ${method} in the resolved era`);
27179
27179
  throw new Error(outcome.message);
27180
27180
  }
27181
27181
  return Promise.resolve(schemasOrHandler(outcome.value, ctx));
27182
27182
  };
27183
- } else if (maybeHandler) stored = async (request2, ctx) => {
27184
- const parsed = await validateStandardSchema(schemasOrHandler.params, { ...request2.params });
27183
+ } else if (maybeHandler) stored = async (request3, ctx) => {
27184
+ const parsed = await validateStandardSchema(schemasOrHandler.params, { ...request3.params });
27185
27185
  if (!parsed.success) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Invalid params for ${method}: ${parsed.error}`);
27186
27186
  return maybeHandler(parsed.data, ctx);
27187
27187
  };
@@ -34694,7 +34694,7 @@ var LegacyInputRequiredShim = class {
34694
34694
  constructor(_host) {
34695
34695
  this._host = _host;
34696
34696
  }
34697
- async fulfill(method, handler, request2, ctx, firstResult) {
34697
+ async fulfill(method, handler, request3, ctx, firstResult) {
34698
34698
  const { maxRounds, roundTimeoutMs } = this._host;
34699
34699
  const outerSignal = ctx.mcpReq.signal;
34700
34700
  let current = firstResult;
@@ -34755,7 +34755,7 @@ var LegacyInputRequiredShim = class {
34755
34755
  const decoded = await this._host.verifyRequestState(requestState, ctxNext, method);
34756
34756
  if (decoded !== void 0) ctxNext = withRequestStateValue(ctxNext, decoded);
34757
34757
  }
34758
- const next = await handler(request2, ctxNext);
34758
+ const next = await handler(request3, ctxNext);
34759
34759
  if (!isInputRequiredResult(next)) return next;
34760
34760
  current = next;
34761
34761
  }
@@ -34845,7 +34845,7 @@ var Server = class extends Protocol {
34845
34845
  for (const [operation2, hint] of Object.entries(options.cacheHints)) if (hint !== void 0) assertValidCacheHint(hint, `cacheHints['${operation2}']`);
34846
34846
  this._cacheHints = options.cacheHints;
34847
34847
  }
34848
- this.setRequestHandler("initialize", (request2) => this._oninitialize(request2));
34848
+ this.setRequestHandler("initialize", (request3) => this._oninitialize(request3));
34849
34849
  this.setNotificationHandler("notifications/initialized", () => this.oninitialized?.());
34850
34850
  if (modernProtocolVersions(this._supportedProtocolVersions).length > 0) this.setRequestHandler("server/discover", () => this._ondiscover());
34851
34851
  if (this._capabilities.logging) this._registerLoggingHandler();
@@ -34858,9 +34858,9 @@ var Server = class extends Protocol {
34858
34858
  * Migrate to stderr logging (STDIO servers) or OpenTelemetry.
34859
34859
  */
34860
34860
  _registerLoggingHandler() {
34861
- this.setRequestHandler("logging/setLevel", async (request2, ctx) => {
34861
+ this.setRequestHandler("logging/setLevel", async (request3, ctx) => {
34862
34862
  const transportSessionId = ctx.sessionId || ctx.http?.req?.headers.get("mcp-session-id") || void 0;
34863
- const { level } = request2.params;
34863
+ const { level } = request3.params;
34864
34864
  const parseResult = parseSchema(LoggingLevelSchema, level);
34865
34865
  if (parseResult.success) this._loggingLevels.set(transportSessionId, parseResult.data);
34866
34866
  return {};
@@ -34934,13 +34934,13 @@ var Server = class extends Protocol {
34934
34934
  if (method !== "tools/call") {
34935
34935
  const cacheHint = this._cacheHints?.[method];
34936
34936
  const isInputRequiredCapable = INPUT_REQUIRED_CAPABLE_METHODS.has(method);
34937
- if (cacheHint === void 0 && !isInputRequiredCapable) return async (request2, ctx) => {
34938
- const result = await handler(request2, ctx);
34937
+ if (cacheHint === void 0 && !isInputRequiredCapable) return async (request3, ctx) => {
34938
+ const result = await handler(request3, ctx);
34939
34939
  if (isInputRequiredResult(result)) throw new ProtocolError(ProtocolErrorCode.InternalError, `Handler for ${method} returned an input-required result, but only tools/call, prompts/get and resources/read support input_required (protocol revision 2026-07-28)`);
34940
34940
  return result;
34941
34941
  };
34942
- return async (request2, ctx) => {
34943
- const result = isInputRequiredCapable ? await this._invokeInputRequiredCapableHandler(method, handler, request2, ctx) : await handler(request2, ctx);
34942
+ return async (request3, ctx) => {
34943
+ const result = isInputRequiredCapable ? await this._invokeInputRequiredCapableHandler(method, handler, request3, ctx) : await handler(request3, ctx);
34944
34944
  if (isInputRequiredResult(result)) {
34945
34945
  if (!isInputRequiredCapable) throw new ProtocolError(ProtocolErrorCode.InternalError, `Handler for ${method} returned an input-required result, but only tools/call, prompts/get and resources/read support input_required (protocol revision 2026-07-28)`);
34946
34946
  return result;
@@ -34948,11 +34948,11 @@ var Server = class extends Protocol {
34948
34948
  return cacheHint === void 0 ? result : attachCacheHintFallback(result, cacheHint);
34949
34949
  };
34950
34950
  }
34951
- return async (request2, ctx) => {
34951
+ return async (request3, ctx) => {
34952
34952
  const codec2 = codecForVersion(this._negotiatedProtocolVersion);
34953
- const validatedRequest = codec2.validateRequest("tools/call", request2);
34953
+ const validatedRequest = codec2.validateRequest("tools/call", request3);
34954
34954
  if (!validatedRequest.ok) throw new ProtocolError(validatedRequest.reason === "not-in-era" ? ProtocolErrorCode.InternalError : ProtocolErrorCode.InvalidParams, validatedRequest.reason === "not-in-era" ? "No wire schema for tools/call in the resolved era" : `Invalid tools/call request: ${validatedRequest.message}`);
34955
- const result = await this._invokeInputRequiredCapableHandler("tools/call", handler, request2, ctx);
34955
+ const result = await this._invokeInputRequiredCapableHandler("tools/call", handler, request3, ctx);
34956
34956
  if (isInputRequiredResult(result)) return result;
34957
34957
  const normalizedResult = normalizeContentlessToolResult(result);
34958
34958
  const validationResult = codec2.validateResult("tools/call", normalizedResult);
@@ -34990,7 +34990,7 @@ var Server = class extends Protocol {
34990
34990
  * violations per family; `inputRequired.legacyShim: false` restores
34991
34991
  * the pre-shim loud failure.
34992
34992
  */
34993
- async _invokeInputRequiredCapableHandler(method, handler, request2, ctx) {
34993
+ async _invokeInputRequiredCapableHandler(method, handler, request3, ctx) {
34994
34994
  const servedModern = this._servedModernEra();
34995
34995
  const rawRequestState = ctx.mcpReq.requestState();
34996
34996
  if (rawRequestState !== void 0 && typeof rawRequestState !== "string") throw new ProtocolError(ProtocolErrorCode.InvalidParams, "Invalid or expired requestState", { reason: "invalid_request_state" });
@@ -35001,7 +35001,7 @@ var Server = class extends Protocol {
35001
35001
  }
35002
35002
  let result;
35003
35003
  try {
35004
- result = await handler(request2, ctxForHandler);
35004
+ result = await handler(request3, ctxForHandler);
35005
35005
  } catch (error51) {
35006
35006
  if (error51 instanceof ProtocolError && error51.code === ProtocolErrorCode.UrlElicitationRequired) {
35007
35007
  if (!servedModern) throw error51;
@@ -35012,7 +35012,7 @@ var Server = class extends Protocol {
35012
35012
  if (!isInputRequiredResult(result)) return result;
35013
35013
  if (!servedModern) {
35014
35014
  if (!this._inputRequiredServing.legacyShim) throw new ProtocolError(ProtocolErrorCode.InternalError, `Handler for ${method} returned an input-required result, but this request is served on protocol revision ${this._negotiatedProtocolVersion ?? LATEST_PROTOCOL_VERSION}, which has no input_required vocabulary`);
35015
- return await this._legacyInputRequiredShim().fulfill(method, handler, request2, ctxForHandler, result);
35015
+ return await this._legacyInputRequiredShim().fulfill(method, handler, request3, ctxForHandler, result);
35016
35016
  }
35017
35017
  const inputRequests = result.inputRequests;
35018
35018
  const hasInputRequests = inputRequests != null && Object.keys(inputRequests).length > 0;
@@ -35131,10 +35131,10 @@ var Server = class extends Protocol {
35131
35131
  break;
35132
35132
  }
35133
35133
  }
35134
- async _oninitialize(request2) {
35135
- const requestedVersion = request2.params.protocolVersion;
35136
- this._clientCapabilities = request2.params.capabilities;
35137
- this._clientVersion = request2.params.clientInfo;
35134
+ async _oninitialize(request3) {
35135
+ const requestedVersion = request3.params.protocolVersion;
35136
+ this._clientCapabilities = request3.params.capabilities;
35137
+ this._clientVersion = request3.params.clientInfo;
35138
35138
  const legacyVersions = legacyProtocolVersions(this._supportedProtocolVersions);
35139
35139
  const protocolVersion = legacyVersions.includes(requestedVersion) ? requestedVersion : legacyVersions[0] ?? LATEST_PROTOCOL_VERSION;
35140
35140
  this._negotiatedProtocolVersion = protocolVersion;
@@ -35487,14 +35487,14 @@ var McpServer = class {
35487
35487
  if (tool.outputSchema) toolDefinition.outputSchema = standardSchemaToJsonSchema(tool.outputSchema, "output");
35488
35488
  return toolDefinition;
35489
35489
  }) }));
35490
- this.server.setRequestHandler("tools/call", async (request2, ctx) => {
35491
- const tool = this._registeredTools[request2.params.name];
35492
- if (!tool) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Tool ${request2.params.name} not found`);
35493
- if (!tool.enabled) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Tool ${request2.params.name} disabled`);
35490
+ this.server.setRequestHandler("tools/call", async (request3, ctx) => {
35491
+ const tool = this._registeredTools[request3.params.name];
35492
+ if (!tool) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Tool ${request3.params.name} not found`);
35493
+ if (!tool.enabled) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Tool ${request3.params.name} disabled`);
35494
35494
  try {
35495
- const args = await this.validateToolInput(tool, request2.params.arguments, request2.params.name);
35495
+ const args = await this.validateToolInput(tool, request3.params.arguments, request3.params.name);
35496
35496
  const result = await this.executeToolHandler(tool, args, ctx);
35497
- await this.validateToolOutput(tool, result, request2.params.name);
35497
+ await this.validateToolOutput(tool, result, request3.params.name);
35498
35498
  if (isInputRequiredResult(result)) return result;
35499
35499
  return this.server.projectCallToolResult(result, tool.outputSchemaJson);
35500
35500
  } catch (error51) {
@@ -35550,40 +35550,40 @@ var McpServer = class {
35550
35550
  if (this._completionHandlerInitialized) return;
35551
35551
  this.server.assertCanSetRequestHandler("completion/complete");
35552
35552
  this.server.registerCapabilities({ completions: {} });
35553
- this.server.setRequestHandler("completion/complete", async (request2) => {
35554
- switch (request2.params.ref.type) {
35553
+ this.server.setRequestHandler("completion/complete", async (request3) => {
35554
+ switch (request3.params.ref.type) {
35555
35555
  case "ref/prompt":
35556
- assertCompleteRequestPrompt(request2);
35557
- return this.handlePromptCompletion(request2, request2.params.ref);
35556
+ assertCompleteRequestPrompt(request3);
35557
+ return this.handlePromptCompletion(request3, request3.params.ref);
35558
35558
  case "ref/resource":
35559
- assertCompleteRequestResourceTemplate(request2);
35560
- return this.handleResourceCompletion(request2, request2.params.ref);
35559
+ assertCompleteRequestResourceTemplate(request3);
35560
+ return this.handleResourceCompletion(request3, request3.params.ref);
35561
35561
  default:
35562
- throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Invalid completion reference: ${request2.params.ref}`);
35562
+ throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Invalid completion reference: ${request3.params.ref}`);
35563
35563
  }
35564
35564
  });
35565
35565
  this._completionHandlerInitialized = true;
35566
35566
  }
35567
- async handlePromptCompletion(request2, ref) {
35567
+ async handlePromptCompletion(request3, ref) {
35568
35568
  const prompt = this._registeredPrompts[ref.name];
35569
35569
  if (!prompt) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Prompt ${ref.name} not found`);
35570
35570
  if (!prompt.enabled) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Prompt ${ref.name} disabled`);
35571
35571
  if (!prompt.argsSchema) return EMPTY_COMPLETION_RESULT;
35572
- const field = unwrapOptionalSchema(getSchemaShape(prompt.argsSchema)?.[request2.params.argument.name]);
35572
+ const field = unwrapOptionalSchema(getSchemaShape(prompt.argsSchema)?.[request3.params.argument.name]);
35573
35573
  if (!isCompletable(field)) return EMPTY_COMPLETION_RESULT;
35574
35574
  const completer = getCompleter(field);
35575
35575
  if (!completer) return EMPTY_COMPLETION_RESULT;
35576
- return createCompletionResult(await completer(request2.params.argument.value, request2.params.context));
35576
+ return createCompletionResult(await completer(request3.params.argument.value, request3.params.context));
35577
35577
  }
35578
- async handleResourceCompletion(request2, ref) {
35578
+ async handleResourceCompletion(request3, ref) {
35579
35579
  const template = Object.values(this._registeredResourceTemplates).find((t) => t.resourceTemplate.uriTemplate.toString() === ref.uri);
35580
35580
  if (!template) {
35581
35581
  if (this._registeredResources[ref.uri]) return EMPTY_COMPLETION_RESULT;
35582
- throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Resource template ${request2.params.ref.uri} not found`);
35582
+ throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Resource template ${request3.params.ref.uri} not found`);
35583
35583
  }
35584
- const completer = template.resourceTemplate.completeCallback(request2.params.argument.name);
35584
+ const completer = template.resourceTemplate.completeCallback(request3.params.argument.name);
35585
35585
  if (!completer) return EMPTY_COMPLETION_RESULT;
35586
- return createCompletionResult(await completer(request2.params.argument.value, request2.params.context));
35586
+ return createCompletionResult(await completer(request3.params.argument.value, request3.params.context));
35587
35587
  }
35588
35588
  _resourceHandlersInitialized = false;
35589
35589
  setResourceRequestHandlers() {
@@ -35616,13 +35616,13 @@ var McpServer = class {
35616
35616
  ...template.metadata
35617
35617
  })) };
35618
35618
  });
35619
- this.server.setRequestHandler("resources/read", async (request2, ctx) => {
35619
+ this.server.setRequestHandler("resources/read", async (request3, ctx) => {
35620
35620
  let uri;
35621
35621
  try {
35622
- uri = new URL(request2.params.uri);
35622
+ uri = new URL(request3.params.uri);
35623
35623
  } catch {
35624
- throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Resource URI ${request2.params.uri} is invalid`, {
35625
- uri: request2.params.uri,
35624
+ throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Resource URI ${request3.params.uri} is invalid`, {
35625
+ uri: request3.params.uri,
35626
35626
  reason: "invalid_uri"
35627
35627
  });
35628
35628
  }
@@ -35635,7 +35635,7 @@ var McpServer = class {
35635
35635
  const variables = template.resourceTemplate.uriTemplate.match(uri.toString());
35636
35636
  if (variables) return attachCacheHintFallback(await template.readCallback(uri, variables, ctx), template.cacheHint);
35637
35637
  }
35638
- throw new ResourceNotFoundError(request2.params.uri);
35638
+ throw new ResourceNotFoundError(request3.params.uri);
35639
35639
  });
35640
35640
  this._resourceHandlersInitialized = true;
35641
35641
  }
@@ -35655,11 +35655,11 @@ var McpServer = class {
35655
35655
  _meta: prompt._meta
35656
35656
  };
35657
35657
  }) }));
35658
- this.server.setRequestHandler("prompts/get", async (request2, ctx) => {
35659
- const prompt = this._registeredPrompts[request2.params.name];
35660
- if (!prompt) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Prompt ${request2.params.name} not found`);
35661
- if (!prompt.enabled) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Prompt ${request2.params.name} disabled`);
35662
- return prompt.handler(request2.params.arguments, ctx);
35658
+ this.server.setRequestHandler("prompts/get", async (request3, ctx) => {
35659
+ const prompt = this._registeredPrompts[request3.params.name];
35660
+ if (!prompt) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Prompt ${request3.params.name} not found`);
35661
+ if (!prompt.enabled) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Prompt ${request3.params.name} disabled`);
35662
+ return prompt.handler(request3.params.arguments, ctx);
35663
35663
  });
35664
35664
  this._promptHandlersInitialized = true;
35665
35665
  }
@@ -36260,7 +36260,7 @@ function serveStdio(factory, options = {}) {
36260
36260
  }
36261
36261
  return false;
36262
36262
  };
36263
- const answerLegacyRejection = (request2, reason, requestedVersion) => {
36263
+ const answerLegacyRejection = (request3, reason, requestedVersion) => {
36264
36264
  const rejection2 = modernOnlyStrictRejection({
36265
36265
  kind: "legacy",
36266
36266
  reason,
@@ -36268,7 +36268,7 @@ function serveStdio(factory, options = {}) {
36268
36268
  }, SUPPORTED_MODERN_PROTOCOL_VERSIONS);
36269
36269
  if (rejection2 === void 0) return Promise.resolve();
36270
36270
  reportError(/* @__PURE__ */ new Error(`Rejected 2025-era request on a modern-only stdio connection (${rejection2.cell}): ${rejection2.message}`));
36271
- return writeErrorResponse(request2.id, rejection2.code, rejection2.message, rejection2.data);
36271
+ return writeErrorResponse(request3.id, rejection2.code, rejection2.message, rejection2.data);
36272
36272
  };
36273
36273
  const onInstanceClosed = (channel) => {
36274
36274
  if (closing || channel === discarding) return;
@@ -38102,8 +38102,8 @@ var Protocol2 = class {
38102
38102
  this._taskStore = _options?.taskStore;
38103
38103
  this._taskMessageQueue = _options?.taskMessageQueue;
38104
38104
  if (this._taskStore) {
38105
- this.setRequestHandler(GetTaskRequestSchema2, async (request2, extra) => {
38106
- const task = await this._taskStore.getTask(request2.params.taskId, extra.sessionId);
38105
+ this.setRequestHandler(GetTaskRequestSchema2, async (request3, extra) => {
38106
+ const task = await this._taskStore.getTask(request3.params.taskId, extra.sessionId);
38107
38107
  if (!task) {
38108
38108
  throw new McpError(ErrorCode.InvalidParams, "Failed to retrieve task: Task not found");
38109
38109
  }
@@ -38111,9 +38111,9 @@ var Protocol2 = class {
38111
38111
  ...task
38112
38112
  };
38113
38113
  });
38114
- this.setRequestHandler(GetTaskPayloadRequestSchema2, async (request2, extra) => {
38114
+ this.setRequestHandler(GetTaskPayloadRequestSchema2, async (request3, extra) => {
38115
38115
  const handleTaskResult = async () => {
38116
- const taskId = request2.params.taskId;
38116
+ const taskId = request3.params.taskId;
38117
38117
  if (this._taskMessageQueue) {
38118
38118
  let queuedMessage;
38119
38119
  while (queuedMessage = await this._taskMessageQueue.dequeue(taskId, extra.sessionId)) {
@@ -38164,9 +38164,9 @@ var Protocol2 = class {
38164
38164
  };
38165
38165
  return await handleTaskResult();
38166
38166
  });
38167
- this.setRequestHandler(ListTasksRequestSchema2, async (request2, extra) => {
38167
+ this.setRequestHandler(ListTasksRequestSchema2, async (request3, extra) => {
38168
38168
  try {
38169
- const { tasks, nextCursor } = await this._taskStore.listTasks(request2.params?.cursor, extra.sessionId);
38169
+ const { tasks, nextCursor } = await this._taskStore.listTasks(request3.params?.cursor, extra.sessionId);
38170
38170
  return {
38171
38171
  tasks,
38172
38172
  nextCursor,
@@ -38176,20 +38176,20 @@ var Protocol2 = class {
38176
38176
  throw new McpError(ErrorCode.InvalidParams, `Failed to list tasks: ${error51 instanceof Error ? error51.message : String(error51)}`);
38177
38177
  }
38178
38178
  });
38179
- this.setRequestHandler(CancelTaskRequestSchema2, async (request2, extra) => {
38179
+ this.setRequestHandler(CancelTaskRequestSchema2, async (request3, extra) => {
38180
38180
  try {
38181
- const task = await this._taskStore.getTask(request2.params.taskId, extra.sessionId);
38181
+ const task = await this._taskStore.getTask(request3.params.taskId, extra.sessionId);
38182
38182
  if (!task) {
38183
- throw new McpError(ErrorCode.InvalidParams, `Task not found: ${request2.params.taskId}`);
38183
+ throw new McpError(ErrorCode.InvalidParams, `Task not found: ${request3.params.taskId}`);
38184
38184
  }
38185
38185
  if (isTerminal(task.status)) {
38186
38186
  throw new McpError(ErrorCode.InvalidParams, `Cannot cancel task in terminal status: ${task.status}`);
38187
38187
  }
38188
- await this._taskStore.updateTaskStatus(request2.params.taskId, "cancelled", "Client cancelled task execution.", extra.sessionId);
38189
- this._clearTaskQueue(request2.params.taskId);
38190
- const cancelledTask = await this._taskStore.getTask(request2.params.taskId, extra.sessionId);
38188
+ await this._taskStore.updateTaskStatus(request3.params.taskId, "cancelled", "Client cancelled task execution.", extra.sessionId);
38189
+ this._clearTaskQueue(request3.params.taskId);
38190
+ const cancelledTask = await this._taskStore.getTask(request3.params.taskId, extra.sessionId);
38191
38191
  if (!cancelledTask) {
38192
- throw new McpError(ErrorCode.InvalidParams, `Task not found after cancellation: ${request2.params.taskId}`);
38192
+ throw new McpError(ErrorCode.InvalidParams, `Task not found after cancellation: ${request3.params.taskId}`);
38193
38193
  }
38194
38194
  return {
38195
38195
  _meta: {},
@@ -38310,14 +38310,14 @@ var Protocol2 = class {
38310
38310
  }
38311
38311
  Promise.resolve().then(() => handler(notification)).catch((error51) => this._onerror(new Error(`Uncaught error in notification handler: ${error51}`)));
38312
38312
  }
38313
- _onrequest(request2, extra) {
38314
- const handler = this._requestHandlers.get(request2.method) ?? this.fallbackRequestHandler;
38313
+ _onrequest(request3, extra) {
38314
+ const handler = this._requestHandlers.get(request3.method) ?? this.fallbackRequestHandler;
38315
38315
  const capturedTransport = this._transport;
38316
- const relatedTaskId = request2.params?._meta?.[RELATED_TASK_META_KEY2]?.taskId;
38316
+ const relatedTaskId = request3.params?._meta?.[RELATED_TASK_META_KEY2]?.taskId;
38317
38317
  if (handler === void 0) {
38318
38318
  const errorResponse = {
38319
38319
  jsonrpc: "2.0",
38320
- id: request2.id,
38320
+ id: request3.id,
38321
38321
  error: {
38322
38322
  code: ErrorCode.MethodNotFound,
38323
38323
  message: "Method not found"
@@ -38335,17 +38335,17 @@ var Protocol2 = class {
38335
38335
  return;
38336
38336
  }
38337
38337
  const abortController = new AbortController();
38338
- this._requestHandlerAbortControllers.set(request2.id, abortController);
38339
- const taskCreationParams = isTaskAugmentedRequestParams2(request2.params) ? request2.params.task : void 0;
38340
- const taskStore = this._taskStore ? this.requestTaskStore(request2, capturedTransport?.sessionId) : void 0;
38338
+ this._requestHandlerAbortControllers.set(request3.id, abortController);
38339
+ const taskCreationParams = isTaskAugmentedRequestParams2(request3.params) ? request3.params.task : void 0;
38340
+ const taskStore = this._taskStore ? this.requestTaskStore(request3, capturedTransport?.sessionId) : void 0;
38341
38341
  const fullExtra = {
38342
38342
  signal: abortController.signal,
38343
38343
  sessionId: capturedTransport?.sessionId,
38344
- _meta: request2.params?._meta,
38344
+ _meta: request3.params?._meta,
38345
38345
  sendNotification: async (notification) => {
38346
38346
  if (abortController.signal.aborted)
38347
38347
  return;
38348
- const notificationOptions = { relatedRequestId: request2.id };
38348
+ const notificationOptions = { relatedRequestId: request3.id };
38349
38349
  if (relatedTaskId) {
38350
38350
  notificationOptions.relatedTask = { taskId: relatedTaskId };
38351
38351
  }
@@ -38355,7 +38355,7 @@ var Protocol2 = class {
38355
38355
  if (abortController.signal.aborted) {
38356
38356
  throw new McpError(ErrorCode.ConnectionClosed, "Request was cancelled");
38357
38357
  }
38358
- const requestOptions = { ...options, relatedRequestId: request2.id };
38358
+ const requestOptions = { ...options, relatedRequestId: request3.id };
38359
38359
  if (relatedTaskId && !requestOptions.relatedTask) {
38360
38360
  requestOptions.relatedTask = { taskId: relatedTaskId };
38361
38361
  }
@@ -38366,7 +38366,7 @@ var Protocol2 = class {
38366
38366
  return await this.request(r, resultSchema, requestOptions);
38367
38367
  },
38368
38368
  authInfo: extra?.authInfo,
38369
- requestId: request2.id,
38369
+ requestId: request3.id,
38370
38370
  requestInfo: extra?.requestInfo,
38371
38371
  taskId: relatedTaskId,
38372
38372
  taskStore,
@@ -38376,16 +38376,16 @@ var Protocol2 = class {
38376
38376
  };
38377
38377
  Promise.resolve().then(() => {
38378
38378
  if (taskCreationParams) {
38379
- this.assertTaskHandlerCapability(request2.method);
38379
+ this.assertTaskHandlerCapability(request3.method);
38380
38380
  }
38381
- }).then(() => handler(request2, fullExtra)).then(async (result) => {
38381
+ }).then(() => handler(request3, fullExtra)).then(async (result) => {
38382
38382
  if (abortController.signal.aborted) {
38383
38383
  return;
38384
38384
  }
38385
38385
  const response = {
38386
38386
  result,
38387
38387
  jsonrpc: "2.0",
38388
- id: request2.id
38388
+ id: request3.id
38389
38389
  };
38390
38390
  if (relatedTaskId && this._taskMessageQueue) {
38391
38391
  await this._enqueueTaskMessage(relatedTaskId, {
@@ -38402,7 +38402,7 @@ var Protocol2 = class {
38402
38402
  }
38403
38403
  const errorResponse = {
38404
38404
  jsonrpc: "2.0",
38405
- id: request2.id,
38405
+ id: request3.id,
38406
38406
  error: {
38407
38407
  code: Number.isSafeInteger(error51["code"]) ? error51["code"] : ErrorCode.InternalError,
38408
38408
  message: error51.message ?? "Internal error",
@@ -38419,8 +38419,8 @@ var Protocol2 = class {
38419
38419
  await capturedTransport?.send(errorResponse);
38420
38420
  }
38421
38421
  }).catch((error51) => this._onerror(new Error(`Failed to send response: ${error51}`))).finally(() => {
38422
- if (this._requestHandlerAbortControllers.get(request2.id) === abortController) {
38423
- this._requestHandlerAbortControllers.delete(request2.id);
38422
+ if (this._requestHandlerAbortControllers.get(request3.id) === abortController) {
38423
+ this._requestHandlerAbortControllers.delete(request3.id);
38424
38424
  }
38425
38425
  });
38426
38426
  }
@@ -38524,11 +38524,11 @@ var Protocol2 = class {
38524
38524
  *
38525
38525
  * @experimental Use `client.experimental.tasks.requestStream()` to access this method.
38526
38526
  */
38527
- async *requestStream(request2, resultSchema, options) {
38527
+ async *requestStream(request3, resultSchema, options) {
38528
38528
  const { task } = options ?? {};
38529
38529
  if (!task) {
38530
38530
  try {
38531
- const result = await this.request(request2, resultSchema, options);
38531
+ const result = await this.request(request3, resultSchema, options);
38532
38532
  yield { type: "result", result };
38533
38533
  } catch (error51) {
38534
38534
  yield {
@@ -38540,7 +38540,7 @@ var Protocol2 = class {
38540
38540
  }
38541
38541
  let taskId;
38542
38542
  try {
38543
- const createResult = await this.request(request2, CreateTaskResultSchema2, options);
38543
+ const createResult = await this.request(request3, CreateTaskResultSchema2, options);
38544
38544
  if (createResult.task) {
38545
38545
  taskId = createResult.task.taskId;
38546
38546
  yield { type: "taskCreated", task: createResult.task };
@@ -38588,7 +38588,7 @@ var Protocol2 = class {
38588
38588
  *
38589
38589
  * Do not use this method to emit notifications! Use notification() instead.
38590
38590
  */
38591
- request(request2, resultSchema, options) {
38591
+ request(request3, resultSchema, options) {
38592
38592
  const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
38593
38593
  return new Promise((resolve3, reject) => {
38594
38594
  const earlyReject = (error51) => {
@@ -38600,9 +38600,9 @@ var Protocol2 = class {
38600
38600
  }
38601
38601
  if (this._options?.enforceStrictCapabilities === true) {
38602
38602
  try {
38603
- this.assertCapabilityForMethod(request2.method);
38603
+ this.assertCapabilityForMethod(request3.method);
38604
38604
  if (task) {
38605
- this.assertTaskCapability(request2.method);
38605
+ this.assertTaskCapability(request3.method);
38606
38606
  }
38607
38607
  } catch (e) {
38608
38608
  earlyReject(e);
@@ -38612,16 +38612,16 @@ var Protocol2 = class {
38612
38612
  options?.signal?.throwIfAborted();
38613
38613
  const messageId = this._requestMessageId++;
38614
38614
  const jsonrpcRequest = {
38615
- ...request2,
38615
+ ...request3,
38616
38616
  jsonrpc: "2.0",
38617
38617
  id: messageId
38618
38618
  };
38619
38619
  if (options?.onprogress) {
38620
38620
  this._progressHandlers.set(messageId, options.onprogress);
38621
38621
  jsonrpcRequest.params = {
38622
- ...request2.params,
38622
+ ...request3.params,
38623
38623
  _meta: {
38624
- ...request2.params?._meta || {},
38624
+ ...request3.params?._meta || {},
38625
38625
  progressToken: messageId
38626
38626
  }
38627
38627
  };
@@ -38825,8 +38825,8 @@ var Protocol2 = class {
38825
38825
  setRequestHandler(requestSchema, handler) {
38826
38826
  const method = getMethodLiteral(requestSchema);
38827
38827
  this.assertRequestHandlerCapability(method);
38828
- this._requestHandlers.set(method, (request2, extra) => {
38829
- const parsed = parseWithCompat(requestSchema, request2);
38828
+ this._requestHandlers.set(method, (request3, extra) => {
38829
+ const parsed = parseWithCompat(requestSchema, request3);
38830
38830
  return Promise.resolve(handler(parsed, extra));
38831
38831
  });
38832
38832
  }
@@ -38941,19 +38941,19 @@ var Protocol2 = class {
38941
38941
  }, { once: true });
38942
38942
  });
38943
38943
  }
38944
- requestTaskStore(request2, sessionId) {
38944
+ requestTaskStore(request3, sessionId) {
38945
38945
  const taskStore = this._taskStore;
38946
38946
  if (!taskStore) {
38947
38947
  throw new Error("No task store configured");
38948
38948
  }
38949
38949
  return {
38950
38950
  createTask: async (taskParams) => {
38951
- if (!request2) {
38951
+ if (!request3) {
38952
38952
  throw new Error("No request provided");
38953
38953
  }
38954
- return await taskStore.createTask(taskParams, request2.id, {
38955
- method: request2.method,
38956
- params: request2.params
38954
+ return await taskStore.createTask(taskParams, request3.id, {
38955
+ method: request3.method,
38956
+ params: request3.params
38957
38957
  }, sessionId);
38958
38958
  },
38959
38959
  getTask: async (taskId) => {
@@ -39244,8 +39244,8 @@ var ExperimentalClientTasks = class {
39244
39244
  *
39245
39245
  * @experimental
39246
39246
  */
39247
- requestStream(request2, resultSchema, options) {
39248
- return this._client.requestStream(request2, resultSchema, options);
39247
+ requestStream(request3, resultSchema, options) {
39248
+ return this._client.requestStream(request3, resultSchema, options);
39249
39249
  }
39250
39250
  };
39251
39251
 
@@ -39410,8 +39410,8 @@ var Client = class extends Protocol2 {
39410
39410
  }
39411
39411
  const method = methodValue;
39412
39412
  if (method === "elicitation/create") {
39413
- const wrappedHandler = async (request2, extra) => {
39414
- const validatedRequest = safeParse3(ElicitRequestSchema2, request2);
39413
+ const wrappedHandler = async (request3, extra) => {
39414
+ const validatedRequest = safeParse3(ElicitRequestSchema2, request3);
39415
39415
  if (!validatedRequest.success) {
39416
39416
  const errorMessage = validatedRequest.error instanceof Error ? validatedRequest.error.message : String(validatedRequest.error);
39417
39417
  throw new McpError(ErrorCode.InvalidParams, `Invalid elicitation request: ${errorMessage}`);
@@ -39425,7 +39425,7 @@ var Client = class extends Protocol2 {
39425
39425
  if (params.mode === "url" && !supportsUrlMode) {
39426
39426
  throw new McpError(ErrorCode.InvalidParams, "Client does not support URL-mode elicitation requests");
39427
39427
  }
39428
- const result = await Promise.resolve(handler(request2, extra));
39428
+ const result = await Promise.resolve(handler(request3, extra));
39429
39429
  if (params.task) {
39430
39430
  const taskValidationResult = safeParse3(CreateTaskResultSchema2, result);
39431
39431
  if (!taskValidationResult.success) {
@@ -39454,14 +39454,14 @@ var Client = class extends Protocol2 {
39454
39454
  return super.setRequestHandler(requestSchema, wrappedHandler);
39455
39455
  }
39456
39456
  if (method === "sampling/createMessage") {
39457
- const wrappedHandler = async (request2, extra) => {
39458
- const validatedRequest = safeParse3(CreateMessageRequestSchema2, request2);
39457
+ const wrappedHandler = async (request3, extra) => {
39458
+ const validatedRequest = safeParse3(CreateMessageRequestSchema2, request3);
39459
39459
  if (!validatedRequest.success) {
39460
39460
  const errorMessage = validatedRequest.error instanceof Error ? validatedRequest.error.message : String(validatedRequest.error);
39461
39461
  throw new McpError(ErrorCode.InvalidParams, `Invalid sampling request: ${errorMessage}`);
39462
39462
  }
39463
39463
  const { params } = validatedRequest.data;
39464
- const result = await Promise.resolve(handler(request2, extra));
39464
+ const result = await Promise.resolve(handler(request3, extra));
39465
39465
  if (params.task) {
39466
39466
  const taskValidationResult = safeParse3(CreateTaskResultSchema2, result);
39467
39467
  if (!taskValidationResult.success) {
@@ -41006,13 +41006,13 @@ var StreamableHTTPClientTransport = class {
41006
41006
  this.onerror?.(new Error(`Maximum reconnection attempts (${maxRetries}) exceeded.`));
41007
41007
  return;
41008
41008
  }
41009
- const delay = this._getNextReconnectionDelay(attemptCount);
41009
+ const delay2 = this._getNextReconnectionDelay(attemptCount);
41010
41010
  this._reconnectionTimeout = setTimeout(() => {
41011
41011
  this._startOrAuthSse(options).catch((error51) => {
41012
41012
  this.onerror?.(new Error(`Failed to reconnect SSE stream: ${error51 instanceof Error ? error51.message : String(error51)}`));
41013
41013
  this._scheduleReconnection(options, attemptCount + 1);
41014
41014
  });
41015
- }, delay);
41015
+ }, delay2);
41016
41016
  }
41017
41017
  _handleSseStream(stream, options, isReconnectable) {
41018
41018
  if (!stream) {
@@ -41515,6 +41515,39 @@ function registerAppResource(server, name, uri, config2, readCallback) {
41515
41515
  );
41516
41516
  }
41517
41517
 
41518
+ // src/tools/video-editor-local/auth.ts
41519
+ var AUTH_DEADLINE_MS = 4 * 6e4;
41520
+ var ERROR_MESSAGE = "Could not connect to Higgsfield. Complete browser sign-in, then try again.";
41521
+ var profileSchema = external_exports.object({ id: external_exports.string().regex(/\S/) });
41522
+ function createEditorAuth(readProfile) {
41523
+ let state = { status: "idle" };
41524
+ let pending;
41525
+ return {
41526
+ status: () => state,
41527
+ start() {
41528
+ if (pending) return state;
41529
+ state = { status: "pending" };
41530
+ const controller = new AbortController();
41531
+ const timer = setTimeout(() => {
41532
+ state = { status: "error", message: ERROR_MESSAGE };
41533
+ controller.abort();
41534
+ }, AUTH_DEADLINE_MS);
41535
+ timer.unref();
41536
+ pending = Promise.resolve().then(() => readProfile(controller.signal)).then((result) => {
41537
+ if (controller.signal.aborted) return;
41538
+ if (result.isError) throw new Error("Identity lookup failed");
41539
+ state = { status: "ready", profile: profileSchema.parse(result.structuredContent) };
41540
+ }).catch(() => {
41541
+ if (!controller.signal.aborted) state = { status: "error", message: ERROR_MESSAGE };
41542
+ }).finally(() => {
41543
+ clearTimeout(timer);
41544
+ pending = void 0;
41545
+ });
41546
+ return state;
41547
+ }
41548
+ };
41549
+ }
41550
+
41518
41551
  // src/tools/video-editor-local/hosted-proxy.ts
41519
41552
  var HOSTED_MCP_URL = "https://openai-mcp.higgsfield.ai/mcp";
41520
41553
  var HOSTED_PANEL_TOOLS = [
@@ -41572,7 +41605,7 @@ function registerHostedProxyTools(server, url2, session = new LocalBrowserSessio
41572
41605
  const previous = connected?.client;
41573
41606
  const next = new Client({
41574
41607
  name: "higgsfield-video-editor-local",
41575
- version: "1.0.3"
41608
+ version: "1.0.5"
41576
41609
  });
41577
41610
  const transport = new StreamableHTTPClientTransport(new URL(url2), {
41578
41611
  requestInit: { headers: { Authorization: `Bearer ${token}` } }
@@ -41587,6 +41620,43 @@ function registerHostedProxyTools(server, url2, session = new LocalBrowserSessio
41587
41620
  }), 6e4).unref();
41588
41621
  return pending;
41589
41622
  }
41623
+ const identity2 = createEditorAuth(async (signal) => {
41624
+ const token = await session.token();
41625
+ signal.throwIfAborted();
41626
+ const next = new Client({ name: "higgsfield-video-editor-identity", version: "1" });
41627
+ const transport = new StreamableHTTPClientTransport(new URL(url2), {
41628
+ requestInit: { headers: { Authorization: `Bearer ${token}` } }
41629
+ });
41630
+ const abort = () => {
41631
+ void next.close().catch(() => void 0);
41632
+ };
41633
+ signal.addEventListener("abort", abort, { once: true });
41634
+ try {
41635
+ await next.connect(transport, { signal, timeout: 3e4 });
41636
+ return await next.callTool({ name: "get_profile", arguments: {} }, void 0, {
41637
+ signal,
41638
+ timeout: 3e4
41639
+ });
41640
+ } finally {
41641
+ signal.removeEventListener("abort", abort);
41642
+ await next.close().catch(() => void 0);
41643
+ }
41644
+ });
41645
+ registerAppTool(
41646
+ server,
41647
+ "video_editing_auth",
41648
+ {
41649
+ title: "Connect the local video editor",
41650
+ description: "Start or inspect the local editor's Higgsfield sign-in without waiting for the browser.",
41651
+ inputSchema: external_exports.strictObject({ action: external_exports.enum(["start", "status"]) }),
41652
+ annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: true },
41653
+ _meta: { ui: { visibility: ["app"] } }
41654
+ },
41655
+ async ({ action }) => {
41656
+ const state = action === "start" ? identity2.start() : identity2.status();
41657
+ return { content: [], structuredContent: state };
41658
+ }
41659
+ );
41590
41660
  for (const name of HOSTED_PANEL_TOOLS)
41591
41661
  registerAppTool(
41592
41662
  server,
@@ -41746,7 +41816,7 @@ async function projectName(directory, root, update) {
41746
41816
 
41747
41817
  // src/tools/video-editor-local/index.ts
41748
41818
  import { readFileSync as readFileSync3 } from "node:fs";
41749
- import { appendFile as appendFile2, link as link3, mkdir as mkdir5, mkdtemp as mkdtemp2, readFile as readFile6, rm as rm5, stat as stat3, writeFile as writeFile5 } from "node:fs/promises";
41819
+ import { appendFile, link as link3, mkdir as mkdir5, mkdtemp as mkdtemp2, readFile as readFile6, rm as rm5, stat as stat3, writeFile as writeFile6 } from "node:fs/promises";
41750
41820
  import { tmpdir as tmpdir2 } from "node:os";
41751
41821
  import { basename as basename2, extname, isAbsolute as isAbsolute2, join as join9, relative as relative2, resolve as resolve2 } from "node:path";
41752
41822
  import { execFile as execFile3 } from "node:child_process";
@@ -41822,7 +41892,7 @@ var cspOrigins = [];
41822
41892
  var directCspOrigins = () => cspOrigins;
41823
41893
  var CORS = {
41824
41894
  "access-control-allow-origin": "*",
41825
- "access-control-allow-methods": "GET, HEAD, POST, OPTIONS",
41895
+ "access-control-allow-methods": "GET, HEAD, POST, PUT, DELETE, OPTIONS",
41826
41896
  "access-control-allow-headers": "range, content-type",
41827
41897
  "access-control-expose-headers": "content-range, content-length, accept-ranges, content-type",
41828
41898
  // An https page reaching loopback (Private Network Access / Local Network Access preflights).
@@ -41935,6 +42005,149 @@ var DirectServer = class {
41935
42005
  }
41936
42006
  };
41937
42007
 
42008
+ // src/shared/video-editor-media-import.ts
42009
+ var STREAMING_MEDIA_PATH = "api/media/stream";
42010
+ var STREAMING_IMPORT_REQUIRED = "This project is still using an older editor backend. Finish its running work, stop that higgsedit dev process, and reopen the project with the updated plugin before importing media.";
42011
+
42012
+ // src/tools/video-editor-local/import-media.ts
42013
+ var REDIRECTS = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
42014
+ function httpsUrl(value) {
42015
+ const url2 = new URL(value);
42016
+ if (url2.protocol !== "https:") throw new Error("Only https URLs can be imported.");
42017
+ return url2;
42018
+ }
42019
+ async function download(fetcher, start, signal) {
42020
+ let url2 = start;
42021
+ for (let redirects = 0; redirects <= 5; redirects++) {
42022
+ const response = await fetcher(url2, { signal, redirect: "manual" });
42023
+ if (!REDIRECTS.has(response.status)) return response;
42024
+ await response.body?.cancel();
42025
+ const location = response.headers.get("location");
42026
+ if (!location) throw new Error("Download redirect is missing its destination.");
42027
+ url2 = httpsUrl(new URL(location, url2).href);
42028
+ }
42029
+ throw new Error("Download has too many redirects.");
42030
+ }
42031
+ async function uploadResult(response) {
42032
+ if (response.status === 404) {
42033
+ await response.body?.cancel();
42034
+ throw new Error(STREAMING_IMPORT_REQUIRED);
42035
+ }
42036
+ if (!response.body)
42037
+ throw new Error(`Media upload returned an empty response (${response.status}).`);
42038
+ const reader = response.body.getReader();
42039
+ const decoder = new TextDecoder();
42040
+ let text = "";
42041
+ let size = 0;
42042
+ try {
42043
+ for (; ; ) {
42044
+ const { value, done } = await reader.read();
42045
+ if (done) break;
42046
+ size += value.byteLength;
42047
+ if (size > 64 * 1024) throw new Error("Media upload response exceeds 64 KiB.");
42048
+ text += decoder.decode(value, { stream: true });
42049
+ }
42050
+ text += decoder.decode();
42051
+ } finally {
42052
+ await reader.cancel().catch(() => void 0);
42053
+ reader.releaseLock();
42054
+ }
42055
+ let result;
42056
+ try {
42057
+ result = JSON.parse(text);
42058
+ } catch {
42059
+ throw new Error(`Media upload returned invalid JSON (${response.status}).`);
42060
+ }
42061
+ if (typeof result !== "object" || result === null || Array.isArray(result))
42062
+ throw new Error("Media upload returned an invalid result.");
42063
+ const object3 = result;
42064
+ if (!response.ok)
42065
+ throw new Error(
42066
+ typeof object3.error === "string" ? object3.error.slice(0, 1e3) : `Media upload failed (${response.status}).`
42067
+ );
42068
+ return object3;
42069
+ }
42070
+ async function importMedia(origin, url2, fileName, signal, options = {}) {
42071
+ const parsed = httpsUrl(url2);
42072
+ const name = (fileName ?? decodeURIComponent(parsed.pathname.split("/").at(-1) ?? "")).replace(/[/\\]/g, "_").replace(/^\.+/, "") || "import";
42073
+ if (/\0/.test(name)) throw new Error("The media file name contains a null character.");
42074
+ const endpoint = new URL(`/${STREAMING_MEDIA_PATH}`, origin);
42075
+ endpoint.searchParams.set("name", name);
42076
+ const controller = new AbortController();
42077
+ const abort = () => controller.abort(signal?.reason);
42078
+ signal?.throwIfAborted();
42079
+ signal?.addEventListener("abort", abort, { once: true });
42080
+ const timeout = setTimeout(
42081
+ () => controller.abort(new Error("Media import exceeded its time limit.")),
42082
+ options.timeoutMs ?? 30 * 6e4
42083
+ );
42084
+ timeout.unref();
42085
+ let idle;
42086
+ const touch = () => {
42087
+ clearTimeout(idle);
42088
+ idle = setTimeout(
42089
+ () => controller.abort(new Error("Media import stalled while waiting for data.")),
42090
+ options.idleMs ?? 6e4
42091
+ );
42092
+ idle.unref();
42093
+ };
42094
+ const fetcher = options.fetch ?? fetch;
42095
+ let source;
42096
+ let reader;
42097
+ const cancelRead = () => {
42098
+ void reader?.cancel(controller.signal.reason).catch(() => void 0);
42099
+ };
42100
+ let bytes = 0;
42101
+ try {
42102
+ touch();
42103
+ source = await download(fetcher, parsed, controller.signal);
42104
+ if (!source.ok) throw new Error(`Download failed (${source.status}).`);
42105
+ if (!source.body) throw new Error("Download returned no media body.");
42106
+ reader = source.body.getReader();
42107
+ const sourceReader = reader;
42108
+ controller.signal.addEventListener("abort", cancelRead, { once: true });
42109
+ const body = new ReadableStream({
42110
+ async pull(stream) {
42111
+ try {
42112
+ const { value, done } = await sourceReader.read();
42113
+ controller.signal.throwIfAborted();
42114
+ if (done) return stream.close();
42115
+ bytes += value.byteLength;
42116
+ touch();
42117
+ stream.enqueue(value);
42118
+ } catch (error51) {
42119
+ stream.error(error51);
42120
+ }
42121
+ },
42122
+ cancel(reason) {
42123
+ return sourceReader.cancel(reason);
42124
+ }
42125
+ });
42126
+ const response = await fetcher(endpoint, {
42127
+ method: "POST",
42128
+ body,
42129
+ duplex: "half",
42130
+ signal: controller.signal
42131
+ });
42132
+ const result = await uploadResult(response);
42133
+ if (typeof result.src !== "string" || !result.src.startsWith("./media/") || result.src.slice("./media/".length).split("/").some((part) => !part || part === "." || part === ".." || /[\\\0]/.test(part)) || !Number.isSafeInteger(result.byteSize) || result.byteSize !== bytes)
42134
+ throw new Error("Media upload returned an invalid file result.");
42135
+ return { src: result.src, bytes };
42136
+ } catch (error51) {
42137
+ if (controller.signal.aborted) throw controller.signal.reason;
42138
+ throw error51;
42139
+ } finally {
42140
+ clearTimeout(timeout);
42141
+ clearTimeout(idle);
42142
+ signal?.removeEventListener("abort", abort);
42143
+ controller.abort();
42144
+ controller.signal.removeEventListener("abort", cancelRead);
42145
+ await reader?.cancel().catch(() => void 0);
42146
+ reader?.releaseLock();
42147
+ if (source?.body && !source.body.locked) await source.body.cancel().catch(() => void 0);
42148
+ }
42149
+ }
42150
+
41938
42151
  // src/tools/video-editor-local/standalone-resource.ts
41939
42152
  import { readFile as readFile4 } from "node:fs/promises";
41940
42153
  import { join as join5 } from "node:path";
@@ -42032,7 +42245,7 @@ var restyleStyleSchema = external_exports.object({
42032
42245
  });
42033
42246
 
42034
42247
  // src/tools/video-editor-local/standalone-resource.ts
42035
- var packageVersion = "1.0.3";
42248
+ var packageVersion = "1.0.5";
42036
42249
  var VIDEO_EDITOR_RESOURCE_URI = packageVersion ? `ui://higgsfield/video-editor-v3-${encodeURIComponent(packageVersion)}.html` : "ui://higgsfield/video-editor-v3.html";
42037
42250
  function panelHtmlPath(env = process.env) {
42038
42251
  return env.VIDEO_EDITOR_LOCAL_HTML?.trim() || join5(import.meta.dirname, "index.html");
@@ -42079,7 +42292,7 @@ function registerPanelResource(server, html2, hosted2 = null) {
42079
42292
 
42080
42293
  // src/tools/video-editor-local/relay.ts
42081
42294
  import { openAsBlob } from "node:fs";
42082
- import { appendFile, mkdtemp, rm as rm3 } from "node:fs/promises";
42295
+ import { mkdtemp, rm as rm3, writeFile as writeFile4 } from "node:fs/promises";
42083
42296
  import { tmpdir } from "node:os";
42084
42297
  import { join as join6 } from "node:path";
42085
42298
  var MAX_CHUNK = 2 << 20;
@@ -42098,8 +42311,17 @@ async function httpTool(origin, call) {
42098
42311
  function checkPath(path2) {
42099
42312
  if (!path2.startsWith("/") || path2.startsWith("//")) throw new Error(`bad path ${path2}`);
42100
42313
  }
42101
- async function send(origin, method, path2, headers, body) {
42102
- const res = await fetch(`${origin}${path2}`, { method, headers, ...body ? { body } : {} });
42314
+ async function send(origin, method, path2, headers, body, signal) {
42315
+ const res = await fetch(`${origin}${path2}`, {
42316
+ method,
42317
+ headers,
42318
+ signal,
42319
+ ...body ? { body } : {}
42320
+ });
42321
+ if (res.status === 404 && path2.startsWith(`/${STREAMING_MEDIA_PATH}?`)) {
42322
+ await res.body?.cancel();
42323
+ throw new Error(STREAMING_IMPORT_REQUIRED);
42324
+ }
42103
42325
  const bytes = Buffer.from(await res.arrayBuffer());
42104
42326
  if (bytes.length > MAX_CHUNK && res.status !== 206)
42105
42327
  throw new Error(`${path2}: ${bytes.length} bytes without a range; ask for a range`);
@@ -42110,49 +42332,110 @@ async function send(origin, method, path2, headers, body) {
42110
42332
  }
42111
42333
  return { status: res.status, headers: kept, body: bytes.toString("base64") };
42112
42334
  }
42113
- var UPLOAD_STALE_MS = 10 * 6e4;
42335
+ function uploadLimit(value, env, fallback) {
42336
+ const limit = value ?? Number(process.env[env] ?? fallback);
42337
+ if (!Number.isSafeInteger(limit) || limit <= 0)
42338
+ throw new Error(`${env} must be a positive integer`);
42339
+ return limit;
42340
+ }
42114
42341
  var UploadParts = class {
42115
42342
  open = /* @__PURE__ */ new Map();
42116
- dir = null;
42117
- async add(origin, part) {
42118
- this.dropStale();
42343
+ maxBytes;
42344
+ maxConcurrent;
42345
+ idleMs;
42346
+ totalMs;
42347
+ constructor(limits = {}) {
42348
+ this.maxBytes = uploadLimit(limits.maxBytes, "HIGGSEDIT_MEDIA_MAX_BYTES", 8 * 1024 ** 3);
42349
+ this.maxConcurrent = uploadLimit(limits.maxConcurrent, "HIGGSEDIT_MEDIA_MAX_CONCURRENT", 4);
42350
+ this.idleMs = uploadLimit(limits.idleMs, "HIGGSEDIT_MEDIA_IDLE_MS", 6e4);
42351
+ this.totalMs = uploadLimit(limits.totalMs, "HIGGSEDIT_MEDIA_TOTAL_MS", 30 * 6e4);
42352
+ }
42353
+ async add(origin, part, signal) {
42354
+ if (!/^[\w-]{8,64}$/.test(part.id)) throw new Error("Invalid upload id");
42355
+ checkPath(part.path);
42119
42356
  let upload = this.open.get(part.id);
42357
+ if (upload && (upload.origin !== origin || upload.path !== part.path))
42358
+ throw new Error("Upload belongs to another project or path");
42359
+ if (part.cancel) {
42360
+ if (upload) await this.drop(part.id, upload);
42361
+ return { cancelled: true };
42362
+ }
42363
+ signal?.throwIfAborted();
42364
+ if (upload?.busy)
42365
+ throw new Error("Upload part is already being written; wait before sending the next part");
42120
42366
  if (!upload) {
42121
42367
  if (part.offset !== 0) throw new Error(`upload ${part.id} is unknown; start at offset 0`);
42122
- checkPath(part.path);
42123
- this.dir ??= mkdtemp(join6(tmpdir(), "video-editor-upload-"));
42124
- upload = {
42125
- file: join6(await this.dir, part.id),
42368
+ if (this.open.size >= this.maxConcurrent)
42369
+ throw new Error("Too many active media uploads; wait for one to finish");
42370
+ const expire = () => {
42371
+ void this.drop(part.id, created).catch(() => void 0);
42372
+ };
42373
+ const created = {
42374
+ origin,
42126
42375
  path: part.path,
42127
42376
  size: 0,
42128
- touched: Date.now()
42377
+ busy: false,
42378
+ abort: new AbortController(),
42379
+ idle: setTimeout(expire, this.idleMs),
42380
+ total: setTimeout(expire, this.totalMs)
42129
42381
  };
42382
+ created.idle.unref();
42383
+ created.total.unref();
42384
+ upload = created;
42130
42385
  this.open.set(part.id, upload);
42131
42386
  }
42132
- if (part.path !== upload.path || part.offset !== upload.size) {
42133
- this.drop(part.id);
42134
- throw new Error(`upload ${part.id}: expected byte ${upload.size} of ${upload.path}`);
42135
- }
42136
- const bytes = Buffer.from(part.part, "base64");
42137
- await appendFile(upload.file, bytes);
42138
- upload.size += bytes.length;
42139
- upload.touched = Date.now();
42140
- if (!part.last) return { received: upload.size };
42141
- this.open.delete(part.id);
42387
+ const current = upload;
42388
+ current.busy = true;
42389
+ let complete = false;
42390
+ const cancel = () => current.abort.abort(signal?.reason);
42391
+ signal?.addEventListener("abort", cancel, { once: true });
42142
42392
  try {
42143
- return await send(origin, "POST", upload.path, new Headers(), await openAsBlob(upload.file));
42393
+ if (part.offset !== current.size)
42394
+ throw new Error(`upload ${part.id}: expected byte ${current.size}`);
42395
+ if (part.part.length > Math.ceil(MAX_CHUNK / 3) * 4)
42396
+ throw new Error("Upload part exceeds 2 MiB");
42397
+ const bytes = Buffer.from(part.part, "base64");
42398
+ if (bytes.toString("base64") !== part.part)
42399
+ throw new Error("Upload part is not valid base64");
42400
+ if (bytes.length > MAX_CHUNK) throw new Error("Upload part exceeds 2 MiB");
42401
+ if (current.size + bytes.length > this.maxBytes)
42402
+ throw new Error(`Upload exceeds ${this.maxBytes} bytes`);
42403
+ current.abort.signal.throwIfAborted();
42404
+ current.directory ??= await mkdtemp(join6(tmpdir(), "video-editor-upload-"));
42405
+ current.abort.signal.throwIfAborted();
42406
+ const file2 = join6(current.directory, "body");
42407
+ await writeFile4(file2, bytes, { flag: "a", mode: 384, signal: current.abort.signal });
42408
+ current.size += bytes.length;
42409
+ current.idle.refresh();
42410
+ if (!part.last) {
42411
+ complete = true;
42412
+ return { received: current.size };
42413
+ }
42414
+ const endpoint = new URL(current.path, origin);
42415
+ if (endpoint.pathname === "/api/media") endpoint.pathname = `/${STREAMING_MEDIA_PATH}`;
42416
+ const result = await send(
42417
+ origin,
42418
+ "POST",
42419
+ endpoint.pathname + endpoint.search,
42420
+ new Headers(),
42421
+ await openAsBlob(file2),
42422
+ current.abort.signal
42423
+ );
42424
+ complete = true;
42425
+ return result;
42144
42426
  } finally {
42145
- await rm3(upload.file, { force: true });
42427
+ signal?.removeEventListener("abort", cancel);
42428
+ current.busy = false;
42429
+ if (!complete || part.last || current.abort.signal.aborted) await this.drop(part.id, current);
42146
42430
  }
42147
42431
  }
42148
- drop(id2) {
42149
- const upload = this.open.get(id2);
42150
- this.open.delete(id2);
42151
- if (upload) void rm3(upload.file, { force: true });
42152
- }
42153
- dropStale() {
42154
- const cutoff = Date.now() - UPLOAD_STALE_MS;
42155
- for (const [id2, upload] of this.open) if (upload.touched < cutoff) this.drop(id2);
42432
+ async drop(id2, upload) {
42433
+ upload.abort.abort(new Error("Media upload cancelled or expired"));
42434
+ clearTimeout(upload.idle);
42435
+ clearTimeout(upload.total);
42436
+ if (upload.busy) return;
42437
+ if (this.open.get(id2) === upload) this.open.delete(id2);
42438
+ if (upload.directory) await rm3(upload.directory, { recursive: true, force: true });
42156
42439
  }
42157
42440
  };
42158
42441
  var reload = (undo) => ({
@@ -42316,11 +42599,71 @@ import {
42316
42599
  rm as rm4,
42317
42600
  stat as stat2,
42318
42601
  utimes,
42319
- writeFile as writeFile4
42602
+ writeFile as writeFile5
42320
42603
  } from "node:fs/promises";
42321
42604
  import { createServer as createServer3 } from "node:net";
42322
42605
  import { homedir as homedir3 } from "node:os";
42323
42606
  import { join as join8 } from "node:path";
42607
+
42608
+ // src/tools/video-editor-local/session-health.ts
42609
+ import { setTimeout as delay } from "node:timers/promises";
42610
+ var PROBE_MS = 2e3;
42611
+ async function request2(origin, path2, timeoutMs, read, method = "GET") {
42612
+ const controller = new AbortController();
42613
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
42614
+ timer.unref();
42615
+ try {
42616
+ const response = await fetch(new URL(path2, origin), { method, signal: controller.signal });
42617
+ return response.ok ? await read(response) : void 0;
42618
+ } catch {
42619
+ return void 0;
42620
+ } finally {
42621
+ controller.abort();
42622
+ clearTimeout(timer);
42623
+ }
42624
+ }
42625
+ async function waitForDevReady(origin, exited, timeoutMs) {
42626
+ const deadline = Date.now() + timeoutMs;
42627
+ let backoff = 50;
42628
+ while (!exited()) {
42629
+ const remaining = deadline - Date.now();
42630
+ if (remaining <= 0) return false;
42631
+ if (await request2(origin, "/api/history", Math.min(PROBE_MS, remaining), async () => true))
42632
+ return !exited();
42633
+ if (exited()) return false;
42634
+ const budget = deadline - Date.now();
42635
+ if (budget <= 0) return false;
42636
+ await delay(Math.min(backoff, budget));
42637
+ if (budget <= backoff) return false;
42638
+ backoff = Math.min(backoff * 2, 1e3);
42639
+ }
42640
+ return false;
42641
+ }
42642
+ async function requestIdleStop(origin) {
42643
+ return await request2(
42644
+ origin,
42645
+ "/api/idle-stop",
42646
+ 1e3,
42647
+ async (response) => {
42648
+ const reader = response.body?.getReader();
42649
+ if (!reader) return false;
42650
+ const chunks = [];
42651
+ let bytes = 0;
42652
+ for (; ; ) {
42653
+ const next = await reader.read();
42654
+ if (next.done) break;
42655
+ bytes += next.value.byteLength;
42656
+ if (bytes > 1024) return false;
42657
+ chunks.push(next.value);
42658
+ }
42659
+ const value = JSON.parse(Buffer.concat(chunks).toString("utf8"));
42660
+ return typeof value === "object" && value !== null && "stopping" in value && value.stopping === true;
42661
+ },
42662
+ "POST"
42663
+ ) === true;
42664
+ }
42665
+
42666
+ // src/tools/video-editor-local/session.ts
42324
42667
  function localStateDirectory(env = process.env) {
42325
42668
  return env.VIDEO_EDITOR_LOCAL_STATE?.trim() || join8(homedir3(), ".higgsfield", "video-editor-local");
42326
42669
  }
@@ -42328,18 +42671,14 @@ var IDLE_MS = 60 * 60 * 1e3;
42328
42671
  var sessionIdOf = (root) => createHash4("sha256").update(root).digest("hex").slice(0, 16);
42329
42672
  var SESSION_ID = /^[0-9a-f]{16}$/;
42330
42673
  var alive = (pid) => {
42331
- if (!pid) return false;
42674
+ if (!Number.isSafeInteger(pid) || !pid || pid < 1) return false;
42332
42675
  try {
42333
42676
  process.kill(pid, 0);
42334
42677
  return true;
42335
- } catch {
42336
- return false;
42678
+ } catch (error51) {
42679
+ return error51.code !== "ESRCH";
42337
42680
  }
42338
42681
  };
42339
- var answers = (origin) => fetch(`${origin}/api/history`, { signal: AbortSignal.timeout(1e3) }).then(
42340
- (r) => r.ok,
42341
- () => false
42342
- );
42343
42682
  var sleep2 = (ms) => new Promise((resolve3) => setTimeout(resolve3, ms));
42344
42683
  var freePort = () => new Promise((resolve3, reject) => {
42345
42684
  const server = createServer3();
@@ -42364,18 +42703,24 @@ async function startDev(root) {
42364
42703
  });
42365
42704
  child.unref();
42366
42705
  const origin = `http://127.0.0.1:${port}`;
42367
- const deadline = Date.now() + READY_MS;
42368
- while (Date.now() < deadline) {
42369
- if (await answers(origin)) return { origin, pid: child.pid ?? 0 };
42370
- if (child.exitCode !== null) break;
42371
- await sleep2(250);
42706
+ let failed = false;
42707
+ const onError = () => {
42708
+ failed = true;
42709
+ };
42710
+ child.once("error", onError);
42711
+ try {
42712
+ if (await waitForDevReady(
42713
+ origin,
42714
+ () => failed || child.exitCode !== null || child.signalCode !== null,
42715
+ READY_MS
42716
+ ))
42717
+ return { origin, pid: child.pid ?? 0 };
42718
+ } finally {
42719
+ child.removeListener("error", onError);
42372
42720
  }
42373
42721
  child.kill();
42374
42722
  throw new Error(`higgsedit dev did not start for ${root}; run \`higgsedit doctor\``);
42375
42723
  }
42376
- var stopPid = (pid) => {
42377
- if (pid && pid !== process.pid && alive(pid)) process.kill(pid);
42378
- };
42379
42724
  var parseRecord = (text) => {
42380
42725
  try {
42381
42726
  const record2 = JSON.parse(text);
@@ -42397,14 +42742,14 @@ function createSessionStore(options = {}) {
42397
42742
  const write = async (id2, record2) => {
42398
42743
  await mkdir4(projects, { recursive: true, mode: 448 });
42399
42744
  const temp = `${file2(id2, "json")}.${randomUUID4()}.tmp`;
42400
- await writeFile4(temp, JSON.stringify(record2), { mode: 384 });
42745
+ await writeFile5(temp, JSON.stringify(record2), { mode: 384 });
42401
42746
  await rename3(temp, file2(id2, "json"));
42402
42747
  };
42403
42748
  const create = async (record2) => {
42404
42749
  await mkdir4(projects, { recursive: true, mode: 448 });
42405
42750
  const target = file2(sessionIdOf(record2.root), "json");
42406
42751
  const temp = `${target}.${randomUUID4()}.tmp`;
42407
- await writeFile4(temp, JSON.stringify(record2), { mode: 384 });
42752
+ await writeFile5(temp, JSON.stringify(record2), { mode: 384 });
42408
42753
  await link2(temp, target).catch((error51) => {
42409
42754
  if (error51.code !== "EEXIST") throw error51;
42410
42755
  });
@@ -42446,7 +42791,7 @@ function createSessionStore(options = {}) {
42446
42791
  for (; ; ) {
42447
42792
  const body = JSON.stringify({ pid: process.pid, at: Date.now() });
42448
42793
  try {
42449
- await writeFile4(lock, body, { flag: "wx", mode: 384 });
42794
+ await writeFile5(lock, body, { flag: "wx", mode: 384 });
42450
42795
  break;
42451
42796
  } catch (error51) {
42452
42797
  if (error51.code !== "EEXIST") throw error51;
@@ -42480,72 +42825,114 @@ function createSessionStore(options = {}) {
42480
42825
  const used = file2(id2, "used");
42481
42826
  const time3 = new Date(at);
42482
42827
  await utimes(used, time3, time3).catch(async () => {
42483
- await writeFile4(used, "", { mode: 384 });
42828
+ await writeFile5(used, "", { mode: 384 });
42484
42829
  await utimes(used, time3, time3);
42485
42830
  });
42486
42831
  };
42487
- const usedAt = async (record2) => (await stat2(file2(sessionIdOf(record2.root), "used")).catch(() => null))?.mtimeMs ?? record2.openedAt;
42832
+ const usedAt = async (record2) => {
42833
+ const id2 = sessionIdOf(record2.root);
42834
+ const written = (await stat2(file2(id2, "used")).catch(() => null))?.mtimeMs ?? record2.openedAt;
42835
+ return Math.max(written, touched.get(id2) ?? -Infinity);
42836
+ };
42837
+ const activityDirectory = (id2) => join8(projects, `${id2}.activity`);
42838
+ const hasActivity = async (id2) => {
42839
+ const names = await readdir2(activityDirectory(id2)).catch((error51) => {
42840
+ if (error51.code === "ENOENT") return [];
42841
+ throw error51;
42842
+ });
42843
+ for (const name of names) {
42844
+ const owner = /^([1-9]\d*)-[0-9a-f-]{36}$/.exec(name);
42845
+ if (!owner || alive(Number(owner[1]))) return true;
42846
+ await rm4(join8(activityDirectory(id2), name), { force: true });
42847
+ }
42848
+ return false;
42849
+ };
42850
+ const recentRecords = async () => {
42851
+ const all = await records();
42852
+ const live = await Promise.all(all.map((record2) => hasProjectFile(record2.root)));
42853
+ return all.filter((_, i) => live[i]).slice(0, RECENT);
42854
+ };
42488
42855
  const session = async (root, origin) => ({
42489
42856
  root,
42490
42857
  id: sessionIdOf(root),
42491
42858
  name: await projectName(directory, root),
42492
42859
  origin
42493
42860
  });
42494
- const healthy = async (record2, cli) => Boolean(record2?.origin && record2.cli === cli && alive(record2.pid)) && await answers(record2.origin);
42495
- const stopIdle = async (keep) => {
42861
+ const running = (record2) => Boolean(record2?.origin && alive(record2.pid));
42862
+ const stopIdle = async () => {
42496
42863
  const live = (await records()).filter((record2) => record2.origin && alive(record2.pid));
42497
42864
  const cutoff = now() - idleMs;
42498
- const idle = (await Promise.all(
42499
- live.filter((record2) => sessionIdOf(record2.root) !== keep).map(async (record2) => ({ record: record2, used: await usedAt(record2) }))
42500
- )).filter(({ used }) => used < cutoff);
42865
+ const idle = (await Promise.all(live.map(async (record2) => ({ record: record2, used: await usedAt(record2) })))).filter(({ used }) => used < cutoff);
42501
42866
  for (const { record: record2 } of idle) {
42502
42867
  const id2 = sessionIdOf(record2.root);
42503
42868
  await locked(id2, async () => {
42504
42869
  const saved = await read(id2);
42505
- if (!saved?.origin || await usedAt(saved) >= cutoff) return;
42506
- stopPid(saved.pid);
42870
+ if (!saved?.origin || await usedAt(saved) >= cutoff || await hasActivity(id2)) return;
42871
+ if (!await requestIdleStop(saved.origin)) return;
42507
42872
  await write(id2, { root: saved.root, openedAt: saved.openedAt });
42873
+ touched.delete(id2);
42508
42874
  });
42509
42875
  }
42510
42876
  };
42877
+ let sweeping;
42878
+ const sweep = () => {
42879
+ if (sweeping) return sweeping;
42880
+ const pending = stopIdle();
42881
+ sweeping = pending;
42882
+ const done = () => {
42883
+ if (sweeping === pending) sweeping = void 0;
42884
+ };
42885
+ void pending.then(done, done);
42886
+ return pending;
42887
+ };
42511
42888
  const chains = /* @__PURE__ */ new Map();
42512
42889
  const serialized = (id2, run) => {
42513
42890
  const next = (chains.get(id2) ?? Promise.resolve()).then(run, run);
42514
- chains.set(
42515
- id2,
42516
- next.catch(() => {
42517
- })
42891
+ const settled = next.then(
42892
+ () => void 0,
42893
+ () => void 0
42518
42894
  );
42895
+ chains.set(id2, settled);
42896
+ void settled.then(() => {
42897
+ if (chains.get(id2) === settled) chains.delete(id2);
42898
+ });
42519
42899
  return next;
42520
42900
  };
42901
+ const reading = /* @__PURE__ */ new Map();
42521
42902
  const ensure = (root, opened) => {
42522
42903
  const id2 = sessionIdOf(root);
42523
- return serialized(id2, async () => {
42524
- const cli = currentCli();
42904
+ const pending = !opened && reading.get(id2);
42905
+ if (pending) return pending;
42906
+ const work = serialized(id2, async () => {
42525
42907
  let saved = await read(id2);
42526
- let started = false;
42527
- if (opened || !await healthy(saved, cli))
42908
+ if (opened || !running(saved))
42528
42909
  saved = await locked(id2, async () => {
42529
42910
  const current = await read(id2);
42530
42911
  const openedAt = opened ? now() : current?.openedAt ?? now();
42531
42912
  let record2;
42532
- if (await healthy(current, cli)) {
42913
+ if (running(current)) {
42533
42914
  record2 = { ...current, openedAt };
42534
42915
  if (opened) await write(id2, record2);
42535
42916
  } else {
42536
- stopPid(current?.pid);
42917
+ const cli = currentCli();
42537
42918
  if (opened) await write(id2, { root, openedAt });
42538
42919
  record2 = { root, ...await start(root), cli, openedAt };
42539
42920
  await write(id2, record2);
42540
- started = true;
42541
42921
  }
42542
42922
  await touch(id2, true);
42543
42923
  return record2;
42544
42924
  });
42545
42925
  else await touch(id2);
42546
- if (started) await stopIdle(id2);
42547
42926
  return session(root, saved.origin);
42548
42927
  });
42928
+ if (!opened) {
42929
+ reading.set(id2, work);
42930
+ const done = () => {
42931
+ if (reading.get(id2) === work) reading.delete(id2);
42932
+ };
42933
+ void work.then(done, done);
42934
+ }
42935
+ return work;
42549
42936
  };
42550
42937
  const locate = async (ref) => {
42551
42938
  if (ref && SESSION_ID.test(ref)) {
@@ -42563,17 +42950,41 @@ function createSessionStore(options = {}) {
42563
42950
  const store = {
42564
42951
  roots,
42565
42952
  /** Stops dev servers unused for an hour; the MCP server runs this on a timer. */
42566
- stopIdle: () => stopIdle(),
42953
+ stopIdle: sweep,
42567
42954
  /** A project's dev server origin as last written, without a health check: the direct route reads it per request. */
42568
42955
  peek(id2) {
42569
42956
  if (!SESSION_ID.test(id2)) return null;
42570
42957
  try {
42571
42958
  const saved = parseRecord(readFileSync2(file2(id2, "json"), "utf8"));
42572
- return saved?.origin && alive(saved.pid) ? { origin: saved.origin } : null;
42959
+ if (!running(saved)) return null;
42960
+ void touch(id2).catch(() => void 0);
42961
+ return { origin: saved.origin };
42573
42962
  } catch {
42574
42963
  return null;
42575
42964
  }
42576
42965
  },
42966
+ /** Pins an operation across MCP processes without heartbeat timers; crashes release on the next sweep. */
42967
+ async withActivity(current, run) {
42968
+ const lease = await locked(current.id, async () => {
42969
+ const saved = await read(current.id);
42970
+ if (!running(saved) || saved.origin !== current.origin)
42971
+ throw new Error(
42972
+ "The local project server changed before this operation. Retry the operation."
42973
+ );
42974
+ const directory2 = activityDirectory(current.id);
42975
+ await mkdir4(directory2, { recursive: true, mode: 448 });
42976
+ const path2 = join8(directory2, `${process.pid}-${randomUUID4()}`);
42977
+ await writeFile5(path2, "", { flag: "wx", mode: 384 });
42978
+ return path2;
42979
+ });
42980
+ try {
42981
+ await touch(current.id, true);
42982
+ return await run();
42983
+ } finally {
42984
+ await rm4(lease, { force: true });
42985
+ await touch(current.id, true);
42986
+ }
42987
+ },
42577
42988
  async open(path2) {
42578
42989
  const root = await resolveProjectDir(path2, roots());
42579
42990
  await migrated();
@@ -42603,9 +43014,16 @@ function createSessionStore(options = {}) {
42603
43014
  },
42604
43015
  /** Recently opened folders that still hold a project, newest first. */
42605
43016
  async recent() {
42606
- const all = (await records()).map((record2) => record2.root);
42607
- const live = await Promise.all(all.map(hasProjectFile));
42608
- return all.filter((_, i) => live[i]).slice(0, RECENT);
43017
+ return (await recentRecords()).map((record2) => record2.root);
43018
+ },
43019
+ /** `recent()` with each folder's last activity: its dev server's last use, else its last open. */
43020
+ async recentActivity() {
43021
+ return Promise.all(
43022
+ (await recentRecords()).map(async (record2) => ({
43023
+ root: record2.root,
43024
+ usedAt: await usedAt(record2)
43025
+ }))
43026
+ );
42609
43027
  },
42610
43028
  /** Projects whose dev server is running, newest opened first; no health check. */
42611
43029
  async live() {
@@ -42794,11 +43212,14 @@ function registerVideoEditorLocalTools(server, options = {}) {
42794
43212
  };
42795
43213
  const scoped = (project, run) => guarded(async () => {
42796
43214
  const session = await store.session(project);
42797
- return withProject(await run(session), await naming(session, project));
43215
+ return withProject(
43216
+ await store.withActivity(session, () => run(session)),
43217
+ await naming(session, project)
43218
+ );
42798
43219
  });
42799
43220
  const mediaScoped = (project, run) => guarded(async () => {
42800
43221
  const session = project ? await store.session(project) : await store.find().catch(() => null);
42801
- const result = await run(session?.root);
43222
+ const result = session ? await store.withActivity(session, () => run(session.root)) : await run(void 0);
42802
43223
  return session ? withProject(result, await naming(session, project)) : result;
42803
43224
  });
42804
43225
  const opened = async (dir) => {
@@ -43001,19 +43422,7 @@ ${LOCAL_PROJECT_GUIDE}`);
43001
43422
  }),
43002
43423
  annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: true }
43003
43424
  },
43004
- async ({ url: url2, file_name, project }) => scoped(project, async ({ root }) => {
43005
- const parsed = new URL(url2);
43006
- if (parsed.protocol !== "https:") throw new Error("Only https URLs can be imported.");
43007
- const response = await fetch(parsed);
43008
- if (!response.ok)
43009
- throw new Error(`Download failed: ${response.status} ${response.statusText}`);
43010
- const bytes = Buffer.from(await response.arrayBuffer());
43011
- const name = (file_name ?? decodeURIComponent(parsed.pathname.split("/").at(-1) ?? "")).replace(/[/\\]/g, "_").replace(/^\.+/, "") || "import";
43012
- const dir = join9(root, "media");
43013
- await mkdir5(dir, { recursive: true });
43014
- const file2 = await newFile(dir, name, (path2) => writeFile5(path2, bytes, { flag: "wx" }));
43015
- return { src: `./media/${file2}`, bytes: bytes.length };
43016
- })
43425
+ async ({ url: url2, file_name, project }, ctx) => scoped(project, async ({ origin }) => importMedia(origin, url2, file_name, ctx.mcpReq.signal))
43017
43426
  );
43018
43427
  server.registerTool(
43019
43428
  "video_editing_preview_frames",
@@ -43331,18 +43740,20 @@ function registerPanelRelay(server, store, stateDirectory, direct) {
43331
43740
  server,
43332
43741
  "video_editing_session",
43333
43742
  {
43334
- description: "Editor: a local project folder (the one `project` names, else the last opened) and the loopback base of the direct route, or why none is open; plus the allowed roots and recent project folders.",
43743
+ description: "Editor: a local project folder (the one `project` names, else the last opened) and the loopback base of the direct route, or why none is open; plus the allowed roots and recent project folders with their names and last activity.",
43335
43744
  inputSchema: { project: sessionArg },
43336
43745
  _meta: appOnly
43337
43746
  },
43338
43747
  async ({ project }) => {
43339
- const recent = await store.recent();
43748
+ const activity = await store.recentActivity();
43749
+ const recent = activity.map(({ root }) => root);
43340
43750
  const names = Object.fromEntries(
43341
43751
  await Promise.all(
43342
43752
  recent.map(async (path2) => [path2, await projectName(stateDirectory, path2)])
43343
43753
  )
43344
43754
  );
43345
- const listed = { roots: store.roots(), recent, names };
43755
+ const usedAt = Object.fromEntries(activity.map(({ root, usedAt: usedAt2 }) => [root, usedAt2]));
43756
+ const listed = { roots: store.roots(), recent, names, usedAt };
43346
43757
  try {
43347
43758
  const session = await store.find(project);
43348
43759
  return reply(
@@ -43363,7 +43774,7 @@ function registerPanelRelay(server, store, stateDirectory, direct) {
43363
43774
  _meta: appOnly
43364
43775
  },
43365
43776
  async ({ lines }) => guarded(async () => {
43366
- await appendFile2(
43777
+ await appendFile(
43367
43778
  join9(stateDirectory, "panel.log"),
43368
43779
  lines.map((line) => `${(/* @__PURE__ */ new Date()).toISOString()} ${line}
43369
43780
  `).join("")
@@ -43399,13 +43810,17 @@ function registerPanelRelay(server, store, stateDirectory, direct) {
43399
43810
  offset: external_exports.number().int().nonnegative(),
43400
43811
  part: external_exports.string().max(4 << 20),
43401
43812
  last: external_exports.boolean(),
43813
+ cancel: external_exports.boolean().optional(),
43402
43814
  project: sessionArg
43403
43815
  },
43404
43816
  _meta: appOnly
43405
43817
  },
43406
- async ({ project, ...part }) => guarded(async () => ({
43407
- ...await uploads.add((await store.session(project)).origin, part)
43408
- }))
43818
+ async ({ project, ...part }, ctx) => guarded(async () => {
43819
+ const session = await store.session(project);
43820
+ return store.withActivity(session, async () => ({
43821
+ ...await uploads.add(session.origin, part, ctx.mcpReq.signal)
43822
+ }));
43823
+ })
43409
43824
  );
43410
43825
  registerAppTool(
43411
43826
  server,
@@ -43461,7 +43876,7 @@ function registerPanelRelay(server, store, stateDirectory, direct) {
43461
43876
  );
43462
43877
  if (size !== offset) throw new Error(`file ${id2}: expected byte ${size}; start again`);
43463
43878
  const bytes = Buffer.from(part, "base64");
43464
- await writeFile5(temp, bytes, { flag: offset === 0 ? "w" : "a" });
43879
+ await writeFile6(temp, bytes, { flag: offset === 0 ? "w" : "a" });
43465
43880
  if (!last) return { received: offset + bytes.length };
43466
43881
  const file2 = await newFile(dir, name, (path2) => link3(temp, path2));
43467
43882
  await rm5(temp, { force: true });
@@ -43513,7 +43928,34 @@ var operation = external_exports.discriminatedUnion("op", [
43513
43928
  })
43514
43929
  ]);
43515
43930
  var timelineInputs = {
43516
- video_editor_read_timeline: external_exports.object({ request_id: id.optional() }),
43931
+ video_editor_read_timeline: external_exports.object({
43932
+ request_id: id.optional(),
43933
+ view: external_exports.enum(["auto", "summary", "clips", "assets"]).optional(),
43934
+ scope: external_exports.enum(["scene", "selection"]).optional(),
43935
+ clip_ids: external_exports.array(id).min(1).max(200).optional(),
43936
+ time_range: external_exports.object({ start: external_exports.number().nonnegative(), end: external_exports.number().positive() }).optional(),
43937
+ offset: external_exports.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER).optional(),
43938
+ limit: external_exports.number().int().min(1).max(100).optional(),
43939
+ expected_revision: id.optional(),
43940
+ text_offset: external_exports.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER).optional()
43941
+ }).strict().refine((input) => !input.time_range || input.time_range.end > input.time_range.start, {
43942
+ message: "time_range.end must be after time_range.start (timeline seconds)."
43943
+ }).refine(
43944
+ (input) => !((input.offset ?? 0) > 0 || (input.text_offset ?? 0) > 0) || Boolean(input.request_id && input.expected_revision),
43945
+ {
43946
+ message: "Continuation requires the original request_id and expected_revision."
43947
+ }
43948
+ ).refine(
43949
+ (input) => input.text_offset === void 0 || input.view === "clips" && input.clip_ids?.length === 1 && !input.offset,
43950
+ {
43951
+ message: "text_offset requires view=clips, exactly one clip_id, and offset=0."
43952
+ }
43953
+ ).refine(
43954
+ (input) => input.view !== "assets" || input.scope === void 0 && input.clip_ids === void 0 && input.time_range === void 0,
43955
+ {
43956
+ message: "Asset pages do not accept clip scope, IDs or time filters."
43957
+ }
43958
+ ),
43517
43959
  video_editor_apply_timeline: external_exports.object({
43518
43960
  request_id: id,
43519
43961
  expected_revision: id,
@@ -43550,7 +43992,7 @@ var TIMELINE_CHANNEL_META = "higgsfield/timeline-channel";
43550
43992
 
43551
43993
  // src/tools/video-editor-timeline/register.ts
43552
43994
  var descriptions = {
43553
- video_editor_read_timeline: "Read the live browser Video Editor timeline, captured selection, assets and revision. Use editor_session_id from the editor context attachment. Omit request_id only for a new task; retain the returned request_id through clarifications even when selection changes. No selection is needed for additions. This is not a local disk project. Read before any timeline edit.",
43995
+ video_editor_read_timeline: "Read the live browser Video Editor timeline, captured selection, assets and revision. Use editor_session_id from the editor context attachment. Omit request_id only for a new task; retain it through clarifications even when selection changes. Small default reads contain the full scene; large reads return selected clips or a first scene page. Use view=summary for paged tracks/counts, view=clips for details, scope=scene|selection, clip_ids and time_range to filter. view=assets pages the entire asset library. Continue with next_read plus editor_session_id; keep its request_id, expected_revision, view, scope and filters. offset/limit page entries for that view. Long text has a text_window; continue with view=clips, one clip_id, text_offset and expected_revision. Partial clip previews must not replace whole clips. IDs and absolute indexes remain valid only for the returned revision. Filters do not expand edit permission. No selection is needed for additions. This is not a local disk project. Read before any timeline edit.",
43554
43996
  video_editor_apply_timeline: "Apply native clip, caption, effect or transition changes to the captured browser timeline. Requires editor_session_id, request_id and expected_revision from read_timeline. Use a unique operation_id and reuse it on retry. The editor validates scope, locks and revision, applies one undoable operation and confirms it before success is returned. Never substitute a standalone file or another project.",
43555
43997
  video_editor_attach_result: "Attach a generated video to its source clip in the live browser timeline. Use editor_session_id and request_id from context. Provide the real job_id immediately for progress and automatic placement, or an uploaded HTTPS result_url and stable result_id. range: source preserves trim/speed, clip is an already trimmed result, extend adds duration. Original stays unchanged. Read the timeline to confirm placement after generation finishes."
43556
43998
  };
@@ -44143,7 +44585,7 @@ function createEditorUpdates(options, start = (done) => new Promise((resolve3, r
44143
44585
  }
44144
44586
  }
44145
44587
  return {
44146
- runningVersion: options?.version ?? "1.0.3" ?? "Source checkout",
44588
+ runningVersion: options?.version ?? "1.0.5" ?? "Source checkout",
44147
44589
  readyVersion: options && selectedDist(options) !== options.dist ? state.active : null,
44148
44590
  channel: options?.channel ?? null,
44149
44591
  supported: options !== null,
@@ -44207,7 +44649,7 @@ var handle = serveStdio(
44207
44649
  const server = new McpServer(
44208
44650
  {
44209
44651
  name: "Higgsfield Video Editor (local)",
44210
- version: "1.0.3"
44652
+ version: "1.0.5"
44211
44653
  },
44212
44654
  { instructions: VIDEO_EDITOR_LOCAL_INSTRUCTIONS }
44213
44655
  );