// Force strict mode and setup for ESM
"use strict";
import {
  GENERATION_MAX_PROMPT_BYTES,
  MAX_REMEMBER_CONTENT_BYTES,
  createWorkspaceMemoryExtractionErrorLogger,
  extractRememberErrorCode,
  formatWorkspaceMemoryDreamSummary,
  formatWorkspaceMemoryForgetSummary,
  isValidServerName,
  redactMcpServersSetting,
  replayTranscriptRecordPage,
  restoreRedactedMcpServersSetting,
  shouldSuppressRememberErrorDetails,
  workspaceMemoryFailureCode,
  workspaceMemoryFailureDiagnostics
} from "./chunk-IKYQMWZ7.js";
import {
  openQwenAsrRealtimeStream,
  openVoiceStream,
  openVoiceStreamWithRetry
} from "./chunk-5VWYKIMW.js";
import {
  SetupGithubError,
  collectSessionData,
  generateExportFilename,
  normalizeSessionData,
  setupGithub,
  toHtml,
  toJson,
  toJsonl,
  toMarkdown
} from "./chunk-RUBITYOH.js";
import "./chunk-2LLVTJVN.js";
import "./chunk-SUARMD4Q.js";
import "./chunk-QHTIBUWB.js";
import "./chunk-L573Z2QZ.js";
import {
  CAPABILITIES_SCHEMA_VERSION,
  CLIENT_ID_HEADER,
  CLIENT_ID_RE,
  ClientMcpSenderRegistry,
  DeviceFlowRegistry,
  MAX_CLIENT_ID_LENGTH,
  MAX_CONCURRENT_VOICE_SESSIONS,
  MAX_SERVER_NAME_LENGTH,
  MAX_SKILL_NAME_LENGTH,
  MAX_TOOL_NAME_LENGTH,
  PathMutexRegistry,
  QWEN_CDP_MCP_COMMAND_ENV,
  TooManyActiveDeviceFlowsError,
  UnsupportedDeviceFlowProviderError,
  UpstreamDeviceFlowError,
  VoiceLeaseAbortError,
  WorkspaceVoiceCoordinator,
  allowOriginCors,
  bearerAuth,
  brandSecret,
  buildDaemonStatusResponse,
  createBridgeFileSystemAdapter,
  createBuildWorkspaceCtx,
  createClientMcpServerProvider,
  createMutationGate,
  createRateLimiter,
  denyBrowserOriginCors,
  detectFromLoopback,
  getAdvertisedServeFeatures,
  getServeProtocolVersions,
  hostAllowlist,
  isBrowserAutomationMcpAvailable,
  isDeepHealthQuery,
  parseAllowOriginPatterns,
  parseAndValidateWorkspaceClientId,
  parseClientIdHeader,
  parseDaemonStatusDetail,
  parseLastEventId,
  parseMaxQueuedQuery,
  parseOptionalWorkspaceCwd,
  parsePermissionVoteBody,
  requireSessionId,
  require_express,
  resolveAcpHttpEnabled,
  resolveCdpMcpCommand,
  safeBody,
  safeLogValue,
  sanitizeForStderr,
  sendJsonBodyParserError,
  setDeviceFlowRegistry,
  setRateLimiter,
  unsafeRevealSecret,
  validateMcpRuntimeServerName
} from "./chunk-KXYJPRT5.js";
import {
  isLoopbackBind
} from "./chunk-RXFQM6FQ.js";
import {
  createDaemonStatusProvider
} from "./chunk-FZWRRLZG.js";
import "./chunk-LXXMOYPL.js";
import "./chunk-T3LXCZZR.js";
import "./chunk-E5Z2AVNV.js";
import {
  createWorkspaceProvidersStatusProvider
} from "./chunk-RINMSDVH.js";
import {
  getAuthTypeFromEnv,
  resolveCliGenerationConfig
} from "./chunk-EP7UQGYV.js";
import {
  snapshotProcessEnv
} from "./chunk-DAIXBHID.js";
import {
  createWorkspaceSkillsStatusProvider
} from "./chunk-L3S5V5O4.js";
import "./chunk-2W3OOD4W.js";
import {
  EMPTY_WORKSPACE_VOICE_UPDATE_ERROR,
  WorkspaceVoiceError,
  buildWorkspaceVoiceSettingsWrites,
  buildWorkspaceVoiceStatus,
  createDaemonWorkspaceService,
  hasConfiguredBatchVoiceTranscriptionModel,
  transcribeWorkspaceVoiceAudio,
  validateWorkspaceVoiceState,
  voiceSettingsScopeToWire
} from "./chunk-2DOL332Q.js";
import {
  PermissionRulesValidationError,
  buildPermissionSettings,
  isPermissionRuleType,
  normalizePermissionRules,
  readPermissionRuleSet
} from "./chunk-AKC232TB.js";
import {
  assertVoiceBaseUrlNetworkAllowed,
  isStreamingVoiceModel,
  resolveVoiceStreamConfig,
  resolveVoiceTranscriptionConfig,
  sanitizeVoiceErrorMessage,
  transcribeVoiceAudio
} from "./chunk-7P5ASBH7.js";
import {
  isVoiceEnabled,
  isVoiceMode,
  readVoiceModel
} from "./chunk-2WNF6DDX.js";
import "./chunk-FSA7ERJ2.js";
import {
  WorkspacePermissionRulesSessionRequiredError,
  WorkspaceSettingsPartialPersistError,
  WorkspaceSkillNotFoundError,
  WorkspaceSkillNotToggleableError
} from "./chunk-OA4JVLSA.js";
import {
  createTotalSessionAdmissionController
} from "./chunk-AVEOWVOM.js";
import {
  createSingleWorkspaceRegistry,
  createWorkspaceSessionOwnerIndex
} from "./chunk-STZQCNN3.js";
import "./chunk-GRC5HGPI.js";
import {
  SessionArtifactAuthorizationError,
  SessionArtifactValidationError,
  createAcpSessionBridge,
  parseSessionSource
} from "./chunk-3PHCBU7I.js";
import "./chunk-PZL23GTM.js";
import {
  EVENT_SCHEMA_VERSION,
  SubscriberLimitExceededError
} from "./chunk-6RLROE6G.js";
import "./chunk-COH43MRJ.js";
import {
  BranchWhilePromptActiveError,
  CancelSentinelCollisionError,
  CdWhilePromptActiveError,
  InvalidClientIdError,
  InvalidPermissionOptionError,
  InvalidRewindTargetError,
  InvalidSessionMetadataError,
  InvalidSessionScopeError,
  McpServerNotFoundError,
  McpServerRestartFailedError,
  PermissionForbiddenError,
  PermissionPolicyNotImplementedError,
  PromptQueueFullError,
  RestoreInProgressError,
  SessionArchivedError,
  SessionArchivingError,
  SessionBusyError,
  SessionConflictError,
  SessionLimitExceededError,
  SessionNotArchivedError,
  SessionNotFoundError,
  SessionShellClientRequiredError,
  SessionShellDisabledError,
  TotalSessionLimitExceededError,
  WorkspaceDrainingError,
  WorkspaceInitConflictError,
  WorkspaceInitPathEscapeError,
  WorkspaceInitRaceError,
  WorkspaceInitSymlinkError,
  WorkspaceMismatchError
} from "./chunk-L4Y55KIS.js";
import "./chunk-WBL3FJEU.js";
import {
  loadChannelsConfig
} from "./chunk-4D44WPU4.js";
import "./chunk-XPAQP74F.js";
import "./chunk-57OAHC2Y.js";
import {
  parseChannelWebhookConfigLenient
} from "./chunk-5CNYZ7TN.js";
import "./chunk-FNX3LGAK.js";
import "./chunk-V6WHFGST.js";
import "./chunk-PRERFC23.js";
import {
  STATUS_SCHEMA_VERSION,
  createIdleWorkspaceMemoryStatus,
  mapDomainErrorToErrorKind
} from "./chunk-LX3DYYB3.js";
import {
  MAX_REGISTERED_WORKSPACES,
  WorkspaceRegistrationStoreCommittedError,
  WorkspaceRegistrationStoreLimitError,
  workspaceRegistrationId
} from "./chunk-OK2LM4HC.js";
import {
  MAX_WORKSPACE_PATH_LENGTH,
  canonicalizeWorkspace,
  canonicalizeWorkspaces
} from "./chunk-W7FJ3N32.js";
import {
  MAX_CHANNEL_STARTUP_FAILURES,
  MAX_CHANNEL_STARTUP_FAILURE_CHANNEL_LENGTH,
  MAX_CHANNEL_STARTUP_FAILURE_CODE_LENGTH,
  MAX_CHANNEL_STARTUP_FAILURE_MESSAGE_LENGTH,
  QWEN_SERVER_TOKEN_ENV,
  isChannelWebhookEnqueueError,
  normalizeWorkerDiagnostic
} from "./chunk-KSZKSE23.js";
import {
  normalizeServeChannelSelection
} from "./chunk-TJTKSVIV.js";
import {
  redactLogCredentials
} from "./chunk-M5GB774H.js";
import "./chunk-5HBA2Z7V.js";
import "./chunk-T2NCM2ET.js";
import {
  sanitizeLogText
} from "./chunk-ZQIYGQCG.js";
import "./chunk-UDXSXLER.js";
import {
  getDialogSettingKeys,
  getModelProvidersOwnerScope,
  getNestedProperty,
  getOwnKeyScope,
  getSettingDefinition,
  getWritableScopes,
  loadSettings,
  validateSettingValue
} from "./chunk-BYFID5BL.js";
import "./chunk-RKUWKYED.js";
import {
  SUPPORTED_LANGUAGES
} from "./chunk-W7RFHI5L.js";
import "./chunk-ENW2BPUW.js";
import "./chunk-GOXKNSDZ.js";
import "./chunk-IDS7MSUP.js";
import "./chunk-QRUIS3DN.js";
import {
  getWorkspaceTrustStatus
} from "./chunk-FXXY6GR5.js";
import "./chunk-ALGGS7UH.js";
import {
  isWithinRoot as isWithinRoot2
} from "./chunk-MR3PXB6E.js";
import {
  writeStderrLine
} from "./chunk-YUZI3WAC.js";
import "./chunk-GLNHPRZT.js";
import "./chunk-VJNBRRZG.js";
import {
  ALL_PROVIDERS,
  BTW_MAX_INPUT_LENGTH,
  BuiltinAgentRegistry,
  Client,
  ClientMcpRegistrar,
  ExtensionManager,
  GROUP_COLOR_OPTIONS,
  IMAGE_CAPABILITY,
  InvalidSessionTranscriptCursorError,
  ModelsConfig,
  RUNTIME_MCP_IF_ABSENT_CONFIG_FLAG,
  SESSION_TRANSCRIPT_MAX_INDEX_BYTES,
  SESSION_TRANSCRIPT_MAX_LIMIT,
  SessionOrganizationError,
  SessionOrganizationService,
  SessionService,
  SessionTranscriptCursorCodec,
  SessionTranscriptPageTooLargeError,
  SessionTranscriptReader,
  SessionTranscriptSnapshotUnavailableError,
  SessionTranscriptTooLargeError,
  StandardFileSystemService,
  StdioClientTransport,
  StreamableHTTPClientTransport,
  SubagentManager,
  TrustGateError,
  WorkspaceMemoryFileTooLargeError,
  WorkspaceMemoryWriteTimeoutError,
  buildUsageDashboard,
  detectLineEnding,
  encodeTextFileContent,
  glob,
  loadIgnoreRules,
  loadUsageHistoryWithLive,
  parseInstallSource,
  redactUrlCredentials,
  resolveBranchName,
  resolveProviderProtocol,
  shouldShowStep,
  stripAnsiAndControl,
  stripTerminalControlSequences,
  watchRepoBranch,
  writeWorkspaceContextFile
} from "./chunk-KN5EBZLT.js";
import "./chunk-T4TZQJ7W.js";
import "./chunk-H6XPXXMH.js";
import "./chunk-5M6IDOMF.js";
import {
  MAX_JOBS,
  nextDurableFireMs
} from "./chunk-A2HWMJVO.js";
import "./chunk-RCEEXIOO.js";
import "./chunk-KKRTYONM.js";
import "./chunk-TV6K2FB4.js";
import "./chunk-E2UVIFI2.js";
import {
  nextFireTime,
  parseCron
} from "./chunk-XU457J4V.js";
import "./chunk-VDDGDZMA.js";
import {
  appendCronRun,
  generateCronTaskId,
  getCronFilePath,
  readCronTasks,
  taskHasLegacyCondition,
  updateCronTasks
} from "./chunk-SPJQO2CE.js";
import "./chunk-SZRN75WQ.js";
import "./chunk-HTO4JFDZ.js";
import "./chunk-CPBF7KYF.js";
import {
  APPROVAL_MODES,
  SubagentError,
  SubagentErrorCode
} from "./chunk-F333XEAU.js";
import "./chunk-6AM5D4ME.js";
import "./chunk-2Z5UX4KI.js";
import "./chunk-ARKANCNX.js";
import "./chunk-L5U3ELZX.js";
import "./chunk-TYLOFD2U.js";
import {
  addDaemonRequestAttribute,
  decodeBufferWithEncodingInfo,
  emitDaemonLog,
  getAllGeminiMdFilenames,
  hashDaemonWorkspace,
  isBinaryFile,
  isWithinRoot,
  recordDaemonBridgeError,
  recordDaemonError,
  recordDaemonHttpRequest,
  recordDaemonHttpResponse,
  withDaemonRequestSpan
} from "./chunk-D5K5YBSN.js";
import "./chunk-4WKAA4KS.js";
import "./chunk-CR3C7WXL.js";
import "./chunk-RTV5TUYB.js";
import "./chunk-VGC4I5JJ.js";
import "./chunk-FBU7WRZI.js";
import "./chunk-Y66VOBRP.js";
import "./chunk-WTNZ6DXB.js";
import "./chunk-JGUT3LWZ.js";
import {
  QwenOAuth2Client,
  QwenOAuthPollError,
  cacheQwenCredentials,
  generatePKCEPair,
  isDeviceAuthorizationSuccess,
  isDeviceTokenPending,
  isDeviceTokenSuccess
} from "./chunk-OKAIGAYW.js";
import "./chunk-ZPAHLFZU.js";
import "./chunk-JESCGQM3.js";
import "./chunk-WIEO4CWB.js";
import "./chunk-XVNQMZ2I.js";
import "./chunk-FEOZBUMT.js";
import "./chunk-VRR65QYW.js";
import "./chunk-A4UCTEB5.js";
import "./chunk-XWRJCPHC.js";
import "./chunk-4LD5APFL.js";
import {
  import_websocket_server
} from "./chunk-TYAMGABM.js";
import "./chunk-FCMNKVXT.js";
import "./chunk-DJ2GSRLV.js";
import "./chunk-LQIDP6K5.js";
import {
  FatalConfigError,
  Storage,
  createDebugLogger,
  runWithoutDebugLogSession
} from "./chunk-7NFB7LBQ.js";
import "./chunk-75DOP5OR.js";
import "./chunk-DMTGGOSA.js";
import "./chunk-YQ3U5MUC.js";
import "./chunk-TB6UDU4T.js";
import {
  init_esbuild_shims
} from "./chunk-5O2XNYP6.js";
import {
  __name,
  __toESM
} from "./chunk-J2S4EL5Y.js";

// packages/cli/src/serve/server.ts
init_esbuild_shims();
var import_express5 = __toESM(require_express(), 1);

// packages/cli/src/serve/acp-http/index.ts
init_esbuild_shims();
import { createHash as createHash3, timingSafeEqual } from "node:crypto";

// packages/cli/src/serve/acp-http/dispatch.ts
init_esbuild_shims();
import path9 from "node:path";

// packages/cli/src/serve/fs/errors.ts
init_esbuild_shims();
var DEFAULT_STATUS_BY_KIND = {
  path_outside_workspace: 400,
  symlink_escape: 400,
  path_not_found: 404,
  binary_file: 422,
  file_too_large: 413,
  hash_mismatch: 409,
  file_already_exists: 409,
  text_not_found: 422,
  ambiguous_text_match: 422,
  untrusted_workspace: 403,
  permission_denied: 403,
  io_error: 503,
  internal_error: 500,
  parse_error: 400
};
var FsError = class extends Error {
  static {
    __name(this, "FsError");
  }
  kind;
  status;
  hint;
  constructor(kind, message, options) {
    super(
      message,
      options?.cause === void 0 ? void 0 : { cause: options.cause }
    );
    this.name = "FsError";
    this.kind = kind;
    this.status = options?.status ?? DEFAULT_STATUS_BY_KIND[kind];
    this.hint = options?.hint;
  }
};
function isFsError(err) {
  return err instanceof FsError;
}
__name(isFsError, "isFsError");
function wrapAsFsError(err, fallbackKind = "internal_error") {
  if (err instanceof FsError) return err;
  const errno = err?.code;
  const message = err instanceof Error ? err.message : "unknown filesystem error";
  switch (errno) {
    case "ENOENT":
      return new FsError("path_not_found", message, { cause: err });
    case "EACCES":
    case "EPERM":
      return new FsError("permission_denied", message, { cause: err });
    case "ELOOP":
      return new FsError("symlink_escape", message, {
        cause: err,
        hint: "symlink chain forms a cycle or exceeds SYMLOOP_MAX"
      });
    case "EISDIR":
      return new FsError("parse_error", message, {
        cause: err,
        hint: "EISDIR \u2014 path is a directory but a regular file was expected"
      });
    case "ENOTDIR":
      return new FsError("parse_error", message, {
        cause: err,
        hint: "ENOTDIR \u2014 a path component is a regular file but a directory was expected"
      });
    case "ENOSPC":
      return new FsError("io_error", message, {
        cause: err,
        hint: "filesystem is full (df -h reporting 100%)"
      });
    case "EIO":
      return new FsError("io_error", message, {
        cause: err,
        hint: "underlying I/O error (failing disk or kernel-level fault)"
      });
    case "EBUSY":
    case "ETXTBSY":
      return new FsError("io_error", message, {
        cause: err,
        hint: "file is busy; another process holds an exclusive handle"
      });
    case "ENAMETOOLONG":
      return new FsError("io_error", message, {
        cause: err,
        hint: "path exceeds the OS PATH_MAX"
      });
    case "EMFILE":
    case "ENFILE":
      return new FsError("io_error", message, {
        cause: err,
        hint: "too many open files; daemon is at file-descriptor limit"
      });
    default:
      return new FsError(fallbackKind, message, { cause: err });
  }
}
__name(wrapAsFsError, "wrapAsFsError");

// packages/cli/src/serve/fs/paths.ts
init_esbuild_shims();
import { promises as fsp } from "node:fs";
import * as path from "node:path";
var ENOENT_TOLERATING_INTENTS = /* @__PURE__ */ new Set([
  "write",
  "stat"
]);
function hasSuspiciousPathPattern(p) {
  if (process.platform === "win32") {
    const colonIndex = p.indexOf(":", 2);
    if (colonIndex !== -1) return true;
  }
  if (process.platform === "win32" && /~\d+/.test(p)) return true;
  if (p.startsWith("\\\\?\\") || p.startsWith("\\\\.\\") || p.startsWith("//?/") || p.startsWith("//./")) {
    return true;
  }
  if (p.startsWith("\\\\") && p.length > 2 && p[2] !== "\\" || p.startsWith("//") && p.length > 2 && p[2] !== "/") {
    return true;
  }
  if (/(^|\/|\\)\.{3,}(\/|\\|$)/.test(p)) return true;
  for (const seg of p.split(/[\\/]/)) {
    if (seg === "" || seg === "." || seg === "..") continue;
    if (/[.\s]+$/.test(seg)) return true;
    if (/(^|\.)(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(\.|$)/i.test(seg)) {
      return true;
    }
  }
  return false;
}
__name(hasSuspiciousPathPattern, "hasSuspiciousPathPattern");
var MAX_ANCESTOR_HOPS = 40;
var CANONICAL_BOUND_CACHE = /* @__PURE__ */ new Map();
function canonicalizeBoundWorkspaceCached(boundWorkspace) {
  const cached = CANONICAL_BOUND_CACHE.get(boundWorkspace);
  if (cached !== void 0) return cached;
  const canonical = canonicalizeWorkspace(boundWorkspace);
  CANONICAL_BOUND_CACHE.set(boundWorkspace, canonical);
  return canonical;
}
__name(canonicalizeBoundWorkspaceCached, "canonicalizeBoundWorkspaceCached");
function canonicalizeBoundWorkspacesCached(boundWorkspaces) {
  const inputs = typeof boundWorkspaces === "string" ? [boundWorkspaces] : boundWorkspaces;
  if (inputs.length === 0) {
    throw new FsError(
      "parse_error",
      "boundWorkspaces must include at least one workspace root"
    );
  }
  const out = [];
  const seen = /* @__PURE__ */ new Set();
  for (const workspace of inputs) {
    const canonical = canonicalizeBoundWorkspaceCached(workspace);
    if (seen.has(canonical)) continue;
    seen.add(canonical);
    out.push(canonical);
  }
  return out;
}
__name(canonicalizeBoundWorkspacesCached, "canonicalizeBoundWorkspacesCached");
function findContainingWorkspace(absolute, boundWorkspaces) {
  let match;
  for (const workspace of boundWorkspaces) {
    if (isWithinRoot(absolute, workspace) && (match === void 0 || workspace.length > match.length)) {
      match = workspace;
    }
  }
  return match;
}
__name(findContainingWorkspace, "findContainingWorkspace");
async function findExistingAncestor(absolute) {
  let current = absolute;
  const tailParts = [];
  for (let i = 0; i < MAX_ANCESTOR_HOPS; i++) {
    let stat2 = null;
    try {
      stat2 = await fsp.stat(current);
    } catch (err) {
      const code = err?.code;
      if (code === "ENOENT" || code === "ENOTDIR") {
      } else {
        throw err;
      }
    }
    if (stat2) {
      if (tailParts.length > 0 && !stat2.isDirectory()) {
        throw new FsError(
          "parse_error",
          `path component is not a directory: ${absolute}`,
          {
            hint: "a non-directory file occupies a path segment"
          }
        );
      }
      return { ancestor: current, tail: tailParts.join(path.sep) };
    }
    const parent = path.dirname(current);
    if (parent === current) {
      throw new FsError(
        "path_not_found",
        `no existing ancestor for ${absolute}`
      );
    }
    tailParts.unshift(path.basename(current));
    current = parent;
  }
  throw new FsError(
    "path_not_found",
    `path traversal exceeded ${MAX_ANCESTOR_HOPS} hops while finding ancestor`,
    {
      hint: "path is too deeply nested or filesystem is responding unexpectedly"
    }
  );
}
__name(findExistingAncestor, "findExistingAncestor");
async function resolveWithinWorkspace(input, boundWorkspaces, intent) {
  if (typeof input !== "string" || input.length === 0) {
    throw new FsError("parse_error", "path must be a non-empty string");
  }
  if (hasSuspiciousPathPattern(input)) {
    throw new FsError(
      "path_outside_workspace",
      `path contains suspicious pattern: ${input}`,
      {
        hint: "paths with NTFS ADS, 8.3 short names, UNC prefixes, or trailing dots are rejected outright"
      }
    );
  }
  const boundCanonicals = canonicalizeBoundWorkspacesCached(boundWorkspaces);
  const primary = boundCanonicals[0];
  if (primary === void 0) {
    throw new FsError(
      "parse_error",
      "boundWorkspaces must include at least one workspace root"
    );
  }
  const absolute = path.resolve(primary, input);
  let boundCanonical = findContainingWorkspace(absolute, boundCanonicals);
  let preResolvedCanonical;
  if (boundCanonical === void 0 && path.isAbsolute(input)) {
    try {
      preResolvedCanonical = await fsp.realpath(absolute);
      boundCanonical = findContainingWorkspace(
        preResolvedCanonical,
        boundCanonicals
      );
    } catch (err) {
      const code = err?.code;
      if (code === "ENOENT" || code === "ENOTDIR") {
        try {
          const { ancestor, tail } = await findExistingAncestor(absolute);
          const ancestorReal = await fsp.realpath(ancestor);
          const canonicalCandidate = tail ? path.join(ancestorReal, tail) : ancestorReal;
          boundCanonical = findContainingWorkspace(
            canonicalCandidate,
            boundCanonicals
          );
          if (boundCanonical !== void 0) {
            const finalPathIsSymlink = await fsp.lstat(absolute).then((stat2) => stat2.isSymbolicLink()).catch((lstatErr) => {
              if (lstatErr.code === "ENOENT" || lstatErr.code === "ENOTDIR") {
                return false;
              }
              throw lstatErr;
            });
            if (!finalPathIsSymlink && ENOENT_TOLERATING_INTENTS.has(intent)) {
              preResolvedCanonical = canonicalCandidate;
            }
          }
        } catch (innerErr) {
          const innerCode = innerErr?.code;
          if (innerCode !== "ENOENT" && innerCode !== "ENOTDIR") {
            throw innerErr;
          }
        }
      } else {
        throw err;
      }
    }
  }
  if (boundCanonical === void 0) {
    throw new FsError(
      "path_outside_workspace",
      `path escapes workspace: ${input}`
    );
  }
  let canonical;
  try {
    canonical = preResolvedCanonical ?? await fsp.realpath(absolute);
  } catch (err) {
    const code = err?.code;
    if (code === "ENOENT" && ENOENT_TOLERATING_INTENTS.has(intent)) {
      let symlinkResolvedCanonical = null;
      try {
        let cursor = absolute;
        const visitedInodes = /* @__PURE__ */ new Set();
        let firstHopTarget = null;
        let resolvedFully = false;
        for (let hop = 0; hop < MAX_ANCESTOR_HOPS; hop++) {
          let linkStat;
          try {
            linkStat = await fsp.lstat(cursor);
          } catch (lstatErr) {
            const lcode = lstatErr?.code;
            if (lcode === "ENOENT" || lcode === "ENOTDIR") {
              resolvedFully = true;
              break;
            }
            throw lstatErr;
          }
          if (!linkStat.isSymbolicLink()) {
            resolvedFully = true;
            break;
          }
          const ino = typeof linkStat.ino === "bigint" ? linkStat.ino : BigInt(linkStat.ino);
          if (ino !== 0n && visitedInodes.has(ino)) {
            throw new FsError(
              "symlink_escape",
              `symlink cycle detected at ${cursor}`,
              { hint: "symlink loops back onto a previously visited inode" }
            );
          }
          if (ino !== 0n) visitedInodes.add(ino);
          const target = await fsp.readlink(cursor);
          const absTarget = path.isAbsolute(target) ? target : path.resolve(path.dirname(cursor), target);
          if (firstHopTarget === null) firstHopTarget = target;
          cursor = absTarget;
        }
        if (!resolvedFully) {
          throw new FsError(
            "symlink_escape",
            `symlink chain exceeded ${MAX_ANCESTOR_HOPS} hops for ${input}`,
            { hint: "symlink chain is too long or contains a cycle" }
          );
        }
        if (firstHopTarget !== null) {
          const { ancestor: targetAncestor, tail: targetTail } = await findExistingAncestor(cursor);
          const targetAncestorReal = await fsp.realpath(targetAncestor);
          const canonicalTarget = targetTail ? path.join(targetAncestorReal, targetTail) : targetAncestorReal;
          if (!boundCanonicals.some((root) => isWithinRoot(canonicalTarget, root))) {
            throw new FsError(
              "symlink_escape",
              `dangling symlink target escapes workspace: ${input}`,
              {
                // Hint must NOT embed the symlink target — `recordDenied`
                // forwards `hint` into `fs.denied` even in privacy mode,
                // and an absolute outside-target string would leak the
                // attacker's intended exfiltration path through audit
                // events. Operators wanting the actual target value
                // run with `QWEN_AUDIT_RAW_PATHS=1` and read it from
                // `relPath` / `message`.
                hint: "symlink chain leaves the workspace; enable QWEN_AUDIT_RAW_PATHS for the resolved target"
              }
            );
          }
          symlinkResolvedCanonical = canonicalTarget;
        }
      } catch (err2) {
        if (err2 instanceof FsError) throw err2;
        const code2 = err2?.code;
        if (code2 !== "ENOENT") throw err2;
      }
      if (symlinkResolvedCanonical !== null) {
        canonical = symlinkResolvedCanonical;
      } else {
        const { ancestor, tail } = await findExistingAncestor(absolute);
        const ancestorReal = await fsp.realpath(ancestor);
        canonical = tail ? path.join(ancestorReal, tail) : ancestorReal;
      }
    } else if (code === "ENOENT") {
      throw new FsError("path_not_found", `path does not exist: ${input}`, {
        cause: err
      });
    } else if (code === "ELOOP") {
      throw new FsError(
        "symlink_escape",
        `symlink loop or chain too long for ${input}`,
        {
          cause: err,
          hint: "a symlink in the path forms a cycle or exceeds SYMLOOP_MAX"
        }
      );
    } else if (code === "EACCES") {
      throw new FsError(
        "permission_denied",
        `permission denied resolving ${input}`,
        { cause: err }
      );
    } else {
      throw err;
    }
  }
  if (!boundCanonicals.some((root) => isWithinRoot(canonical, root))) {
    const kind = canonical !== absolute ? "symlink_escape" : "path_outside_workspace";
    throw new FsError(
      kind,
      kind === "symlink_escape" ? `symlink resolves outside workspace: ${input}` : `path escapes workspace: ${input}`
    );
  }
  return canonical;
}
__name(resolveWithinWorkspace, "resolveWithinWorkspace");

// packages/cli/src/serve/fs/index.ts
init_esbuild_shims();

// packages/cli/src/serve/fs/policy.ts
init_esbuild_shims();
import * as path2 from "node:path";
var MAX_READ_BYTES = 256 * 1024;
var MAX_WRITE_BYTES = 5 * 1024 * 1024;
function shouldIgnore(absolute, boundWorkspace, ignore, kind = "file") {
  const rel = path2.relative(boundWorkspace, absolute);
  if (rel === "" || rel.startsWith("..")) return { ignored: false };
  const fileFilter = ignore.getFileFilter();
  const dirFilter = ignore.getDirectoryFilter();
  if (kind === "directory") {
    const withSlash = rel.endsWith("/") ? rel : `${rel}/`;
    if (dirFilter(withSlash)) return { ignored: true, category: "directory" };
    if (fileFilter(rel)) return { ignored: true, category: "file" };
    return { ignored: false };
  }
  if (fileFilter(rel)) return { ignored: true, category: "file" };
  if (dirFilter(rel)) return { ignored: true, category: "directory" };
  return { ignored: false };
}
__name(shouldIgnore, "shouldIgnore");
function assertTrustedForIntent(trusted, intent) {
  if (trusted) return;
  switch (intent) {
    case "read":
    case "list":
    case "glob":
    case "stat":
      return;
    case "write":
    case "edit":
      throw new FsError(
        "untrusted_workspace",
        `workspace is not trusted; ${intent} operations are forbidden`,
        {
          hint: "mark the folder as trusted in the daemon configuration to allow writes"
        }
      );
    default: {
      const _exhaustive = intent;
      throw new FsError(
        "untrusted_workspace",
        `workspace is not trusted; intent "${String(_exhaustive)}" is not classified`,
        {
          hint: "unknown intent reached the trust gate; classify it in policy.ts"
        }
      );
    }
  }
}
__name(assertTrustedForIntent, "assertTrustedForIntent");
function enforceReadSize(fileBytes, maxBytes = MAX_READ_BYTES) {
  if (fileBytes <= maxBytes) {
    return { bytesToRead: fileBytes, truncated: false };
  }
  return { bytesToRead: maxBytes, truncated: true };
}
__name(enforceReadSize, "enforceReadSize");
function enforceWriteSize(bytes, maxBytes = MAX_WRITE_BYTES) {
  if (bytes > maxBytes) {
    throw new FsError(
      "file_too_large",
      `payload of ${bytes} bytes exceeds write limit of ${maxBytes} bytes`,
      {
        hint: "split the write into smaller chunks or raise the daemon limit"
      }
    );
  }
}
__name(enforceWriteSize, "enforceWriteSize");
async function detectBinary(filePath) {
  return isBinaryFile(filePath);
}
__name(detectBinary, "detectBinary");

// packages/cli/src/serve/fs/audit.ts
init_esbuild_shims();
import { createHash } from "node:crypto";
import * as path3 from "node:path";
var FS_ACCESS_EVENT_TYPE = "fs.access";
var FS_DENIED_EVENT_TYPE = "fs.denied";
function hashPath(absolute) {
  return createHash("sha256").update(absolute).digest("hex").slice(0, 16);
}
__name(hashPath, "hashPath");
var CROSS_DRIVE_RELPATH = "<cross-drive>";
function relForAudit(raw, boundWorkspace) {
  const rel = path3.isAbsolute(raw) ? path3.relative(boundWorkspace, raw) : raw;
  return path3.isAbsolute(rel) ? CROSS_DRIVE_RELPATH : rel;
}
__name(relForAudit, "relForAudit");
function rawPathsEnabled() {
  return process.env["QWEN_AUDIT_RAW_PATHS"] === "1";
}
__name(rawPathsEnabled, "rawPathsEnabled");
function createAuditPublisher(deps) {
  const includeRawPaths = deps.includeRawPaths ?? rawPathsEnabled();
  const { emit, boundWorkspace } = deps;
  return {
    recordAccess(ctx, record) {
      const absolute = String(record.absolute);
      const payload = {
        kind: FS_ACCESS_EVENT_TYPE,
        intent: record.intent,
        route: ctx.route,
        pathHash: hashPath(absolute),
        durationMs: record.durationMs
      };
      if (ctx.sessionId) payload.sessionId = ctx.sessionId;
      if (record.sizeBytes !== void 0) payload.sizeBytes = record.sizeBytes;
      if (record.truncated) payload.truncated = true;
      if (record.matchedIgnore) payload.matchedIgnore = record.matchedIgnore;
      if (record.pattern !== void 0 && includeRawPaths) {
        payload.pattern = record.pattern;
      }
      if (includeRawPaths) {
        payload.relPath = relForAudit(absolute, boundWorkspace);
      }
      emit({
        v: EVENT_SCHEMA_VERSION,
        type: FS_ACCESS_EVENT_TYPE,
        data: payload,
        originatorClientId: ctx.originatorClientId
      });
    },
    recordDenied(ctx, record) {
      const probe = path3.isAbsolute(record.input) ? record.input : path3.resolve(boundWorkspace, record.input);
      const payload = {
        kind: FS_DENIED_EVENT_TYPE,
        intent: record.intent,
        route: ctx.route,
        pathHash: hashPath(probe),
        errorKind: record.errorKind
      };
      if (ctx.sessionId) payload.sessionId = ctx.sessionId;
      if (record.hint) payload.hint = record.hint;
      if (record.message && includeRawPaths) {
        payload.message = record.message;
      }
      if (record.pattern !== void 0 && includeRawPaths) {
        payload.pattern = record.pattern;
      }
      if (includeRawPaths) {
        payload.relPath = relForAudit(record.input, boundWorkspace);
      }
      emit({
        v: EVENT_SCHEMA_VERSION,
        type: FS_DENIED_EVENT_TYPE,
        data: payload,
        originatorClientId: ctx.originatorClientId
      });
    }
  };
}
__name(createAuditPublisher, "createAuditPublisher");

// packages/cli/src/serve/fs/workspace-file-system.ts
init_esbuild_shims();
import { createHash as createHash2, randomBytes } from "node:crypto";
import { constants as fsConstants, promises as fsp2 } from "node:fs";
import * as path4 from "node:path";
function createWorkspaceFileSystemFactory(deps) {
  const boundWorkspaces = canonicalizeWorkspaces(deps.boundWorkspaces);
  if (boundWorkspaces.length === 0) {
    throw new Error("WorkspaceFileSystem requires at least one workspace root");
  }
  assertNoNestedWorkspaces(boundWorkspaces);
  const primaryWorkspace = boundWorkspaces[0];
  const workspaces = boundWorkspaces.map((workspace) => {
    const ignore = deps.ignore ?? loadIgnoreRules({
      projectRoot: workspace,
      useGitignore: true,
      useQwenignore: true,
      ...deps.customIgnoreFiles !== void 0 ? { customIgnoreFiles: deps.customIgnoreFiles } : {},
      ignoreDirs: []
    });
    Object.freeze(ignore);
    return { path: workspace, ignore };
  });
  const audit = createAuditPublisher({
    emit: deps.emit,
    boundWorkspace: primaryWorkspace,
    includeRawPaths: deps.includeRawPaths
  });
  const lowFs = new StandardFileSystemService();
  const pathLocks = deps.pathLocks ?? new PathMutexRegistry();
  return {
    assertCanWrite() {
      assertTrustedForIntent(deps.trusted, "write");
    },
    forRequest(ctx) {
      return new WorkspaceFileSystemImpl({
        primaryWorkspace,
        workspaces,
        trusted: deps.trusted,
        audit,
        ctx,
        lowFs,
        pathLocks
      });
    }
  };
}
__name(createWorkspaceFileSystemFactory, "createWorkspaceFileSystemFactory");
function assertNoNestedWorkspaces(workspaces) {
  for (let i = 0; i < workspaces.length; i++) {
    const a = workspaces[i];
    if (a === void 0) continue;
    for (let j = i + 1; j < workspaces.length; j++) {
      const b = workspaces[j];
      if (b === void 0) continue;
      if (isWithinRoot(a, b) || isWithinRoot(b, a)) {
        throw new Error(
          `Nested workspace roots are not supported: ${JSON.stringify(
            a
          )} and ${JSON.stringify(b)}`
        );
      }
    }
  }
}
__name(assertNoNestedWorkspaces, "assertNoNestedWorkspaces");
var WorkspaceFileSystemImpl = class {
  constructor(deps) {
    this.deps = deps;
  }
  static {
    __name(this, "WorkspaceFileSystemImpl");
  }
  workspaceForPath(p) {
    let match;
    for (const workspace of this.deps.workspaces) {
      if (isWithinRoot(p, workspace.path) && (match === void 0 || workspace.path.length > match.path.length)) {
        match = workspace;
      }
    }
    return match;
  }
  ignoreVerdict(p, kind = "file") {
    const workspace = this.workspaceForPath(p);
    if (!workspace) return { ignored: false };
    return shouldIgnore(p, workspace.path, workspace.ignore, kind);
  }
  async resolve(input, intent) {
    try {
      return await resolveWithinWorkspace(
        input,
        this.deps.workspaces.map((workspace) => workspace.path),
        intent
      );
    } catch (err) {
      throw this.recordAndWrap(err, intent, input);
    }
  }
  async stat(p) {
    const start = performance.now();
    try {
      assertTrustedForIntent(this.deps.trusted, "stat");
      const st = await fsp2.lstat(p);
      const out = {
        kind: kindFromStatLike(st),
        sizeBytes: st.size,
        modifiedMs: st.mtimeMs
      };
      this.deps.audit.recordAccess(this.deps.ctx, {
        intent: "stat",
        absolute: p,
        durationMs: performance.now() - start,
        sizeBytes: st.size
      });
      return out;
    } catch (err) {
      throw this.recordAndWrap(err, "stat", p);
    }
  }
  async readText(p, opts = {}) {
    const start = performance.now();
    try {
      assertTrustedForIntent(this.deps.trusted, "read");
      if (opts.line !== void 0 && (!Number.isSafeInteger(opts.line) || opts.line < 1)) {
        throw new FsError(
          "parse_error",
          `line must be a positive integer, got ${opts.line}`
        );
      }
      if (opts.limit !== void 0 && (!Number.isSafeInteger(opts.limit) || opts.limit < 1)) {
        throw new FsError(
          "parse_error",
          `limit must be a positive integer, got ${opts.limit}`
        );
      }
      const snapshot = await readTextSnapshotFromResolvedFile(p, opts);
      const ignoreVerdict = this.ignoreVerdict(p, "file");
      const meta = snapshot.meta;
      if (ignoreVerdict.ignored) meta.matchedIgnore = ignoreVerdict.category;
      this.deps.audit.recordAccess(this.deps.ctx, {
        intent: "read",
        absolute: p,
        durationMs: performance.now() - start,
        sizeBytes: meta.sizeBytes,
        truncated: meta.truncated,
        matchedIgnore: meta.matchedIgnore
      });
      return { content: snapshot.content, meta };
    } catch (err) {
      throw this.recordAndWrap(err, "read", p);
    }
  }
  async readBytes(p, opts = {}) {
    const out = await this.readBytesWindow(p, opts);
    return out.buffer;
  }
  async readBytesWindow(p, opts = {}) {
    const start = performance.now();
    try {
      assertTrustedForIntent(this.deps.trusted, "read");
      const offset = opts.offset ?? 0;
      const maxBytes = opts.maxBytes ?? MAX_READ_BYTES;
      if (!Number.isSafeInteger(offset) || offset < 0) {
        throw new FsError(
          "parse_error",
          `offset must be a non-negative integer, got ${offset}`
        );
      }
      if (!Number.isSafeInteger(maxBytes) || maxBytes < 1 || maxBytes > MAX_READ_BYTES) {
        throw new FsError(
          "parse_error",
          `maxBytes must be a positive integer in [1, ${MAX_READ_BYTES}], got ${maxBytes}`
        );
      }
      const pre = await fsp2.lstat(p);
      if (!pre.isFile()) {
        throw new FsError("parse_error", `path is not a regular file: ${p}`);
      }
      const fh = await fsp2.open(p, "r");
      let st;
      let buf;
      try {
        st = await fh.stat();
        assertSameFile(pre, st, p, "read");
        const available = Math.max(0, st.size - offset);
        const toRead = Math.min(maxBytes, available);
        buf = Buffer.allocUnsafe(toRead);
        if (toRead > 0) {
          const read = await fh.read(buf, 0, toRead, offset);
          buf = read.bytesRead === toRead ? buf : buf.subarray(0, read.bytesRead);
        }
        const afterRead = await fh.stat();
        assertSameFile(st, afterRead, p, "read");
        if (afterRead.size !== st.size || afterRead.mtimeMs !== st.mtimeMs) {
          throw new FsError("hash_mismatch", `file changed during read: ${p}`, {
            hint: "retry after re-reading the latest file hash"
          });
        }
      } finally {
        await fh.close();
      }
      await assertInodeStableAfterRead(p, st.ino);
      const fullWindow = offset === 0 && buf.length === st.size;
      const out = {
        buffer: buf,
        sizeBytes: st.size,
        returnedBytes: buf.length,
        offset,
        truncated: !fullWindow,
        ...fullWindow ? { hash: hashBuffer(buf) } : {}
      };
      this.deps.audit.recordAccess(this.deps.ctx, {
        intent: "read",
        absolute: p,
        durationMs: performance.now() - start,
        sizeBytes: buf.length,
        truncated: out.truncated
      });
      return out;
    } catch (err) {
      throw this.recordAndWrap(err, "read", p);
    }
  }
  async list(p, opts = {}) {
    const start = performance.now();
    try {
      assertTrustedForIntent(this.deps.trusted, "list");
      if (opts.maxEntries !== void 0 && (!Number.isSafeInteger(opts.maxEntries) || opts.maxEntries < 1)) {
        throw new FsError(
          "parse_error",
          `maxEntries must be a positive integer, got ${opts.maxEntries}`
        );
      }
      const entries = [];
      const dir = await fsp2.opendir(p);
      for await (const d of dir) {
        const childAbs = path4.join(p, d.name);
        const kind = kindFromStatLike(d);
        const verdict = this.ignoreVerdict(
          childAbs,
          kind === "directory" ? "directory" : "file"
        );
        if (verdict.ignored && !opts.includeIgnored) continue;
        entries.push({ name: d.name, kind, ignored: verdict.ignored });
        if (opts.maxEntries !== void 0 && entries.length >= opts.maxEntries) {
          break;
        }
      }
      this.deps.audit.recordAccess(this.deps.ctx, {
        intent: "list",
        absolute: p,
        durationMs: performance.now() - start,
        sizeBytes: entries.length,
        truncated: opts.maxEntries !== void 0 && entries.length >= opts.maxEntries
      });
      return entries;
    } catch (err) {
      throw this.recordAndWrap(err, "list", p);
    }
  }
  async glob(pattern, opts = {}) {
    const start = performance.now();
    try {
      assertTrustedForIntent(this.deps.trusted, "glob");
      if (pattern.split(/[\\/]/).some((seg) => seg === "..")) {
        throw new FsError(
          "parse_error",
          `glob pattern may not contain '..' segments: ${pattern}`
        );
      }
      if (path4.isAbsolute(pattern) || /^[A-Za-z]:[\\/]/.test(pattern) || pattern.startsWith("\\\\") || pattern.startsWith("//")) {
        throw new FsError(
          "parse_error",
          `glob pattern must be workspace-relative: ${pattern}`,
          { hint: 'pass a relative pattern such as "src/**/*.ts"' }
        );
      }
      const searchRoots = [];
      if (opts.cwd === void 0) {
        for (const workspace of this.deps.workspaces) {
          searchRoots.push({ cwd: workspace.path, workspace });
        }
      } else {
        const cwd = opts.cwd;
        let cwdReal;
        const directWorkspace = this.workspaceForPath(cwd);
        if (directWorkspace && cwd === directWorkspace.path) {
          cwdReal = cwd;
        } else {
          try {
            cwdReal = await fsp2.realpath(path4.resolve(cwd));
          } catch (err) {
            const code = err?.code;
            if (code === "ENOENT") {
              throw new FsError(
                "path_not_found",
                `glob cwd does not exist: ${cwd}`,
                { cause: err }
              );
            }
            throw err;
          }
        }
        const workspace = this.workspaceForPath(cwdReal);
        if (!workspace) {
          throw new FsError(
            "path_outside_workspace",
            `glob cwd is outside workspace: ${cwd}`,
            { hint: "opts.cwd must be a path obtained from fs.resolve()" }
          );
        }
        searchRoots.push({ cwd: cwdReal, workspace });
      }
      const out = [];
      const seenCanonicals = /* @__PURE__ */ new Set();
      const max = opts.maxResults ?? Number.POSITIVE_INFINITY;
      let escapedCount = 0;
      let permissionErrorCount = 0;
      let transientErrorCount = 0;
      const globErrors = [];
      let successfulGlobRoots = 0;
      for (const searchRoot of searchRoots) {
        if (out.length >= max) break;
        let matches;
        try {
          await fsp2.access(searchRoot.cwd, fsConstants.R_OK | fsConstants.X_OK);
          const rootStat = await fsp2.stat(searchRoot.cwd);
          if (!rootStat.isDirectory()) {
            const err = new Error(
              `glob workspace root is not a directory: ${searchRoot.cwd}`
            );
            err.code = "ENOTDIR";
            throw err;
          }
          matches = await glob(pattern, {
            cwd: searchRoot.cwd,
            nodir: false,
            absolute: true,
            dot: true,
            ignore: ["**/node_modules/**", "**/.git/**"]
          });
        } catch (err) {
          globErrors.push(err);
          this.deps.audit.recordDenied(this.deps.ctx, {
            intent: "glob",
            input: pattern,
            errorKind: errorKindForRealpathFailure(err),
            hint: `glob failed for workspace root: ${errorCode(err) ?? "unknown error"}`,
            pattern
          });
          continue;
        }
        successfulGlobRoots += 1;
        for (const hit of matches) {
          if (out.length >= max) break;
          const absolute = path4.resolve(hit);
          let canonical;
          try {
            canonical = await fsp2.realpath(absolute);
          } catch (err) {
            const code = errorCode(err);
            if (code === "ENOENT" || code === "ELOOP") {
              escapedCount += 1;
            } else if (code === "EACCES" || code === "EPERM") {
              permissionErrorCount += 1;
            } else {
              transientErrorCount += 1;
            }
            continue;
          }
          const inAnyWorkspace = this.deps.workspaces.some(
            (workspace) => isWithinRoot(canonical, workspace.path)
          );
          if (!inAnyWorkspace) {
            escapedCount += 1;
            continue;
          }
          if (seenCanonicals.has(canonical)) continue;
          let dirent = null;
          try {
            dirent = await fsp2.lstat(canonical);
          } catch {
            dirent = null;
          }
          const kind = dirent?.isDirectory() ? "directory" : "file";
          const verdict = this.ignoreVerdict(canonical, kind);
          if (verdict.ignored && !opts.includeIgnored) continue;
          seenCanonicals.add(canonical);
          out.push(canonical);
        }
      }
      if (globErrors.length > 0 && successfulGlobRoots === 0) {
        if (globErrors.length === 1) throw globErrors[0];
        throw new AggregateError(
          globErrors,
          "glob failed for all workspace roots"
        );
      }
      if (escapedCount > 0) {
        this.deps.audit.recordDenied(this.deps.ctx, {
          intent: "glob",
          input: pattern,
          errorKind: "symlink_escape",
          hint: `glob filtered ${escapedCount} hit(s) that resolved outside workspace`,
          pattern
        });
      }
      if (permissionErrorCount > 0) {
        this.deps.audit.recordDenied(this.deps.ctx, {
          intent: "glob",
          input: pattern,
          errorKind: "permission_denied",
          hint: `glob skipped ${permissionErrorCount} hit(s) due to EACCES/EPERM`,
          pattern
        });
      }
      if (transientErrorCount > 0) {
        this.deps.audit.recordDenied(this.deps.ctx, {
          intent: "glob",
          input: pattern,
          errorKind: "io_error",
          hint: `glob skipped ${transientErrorCount} hit(s) due to transient I/O errors`,
          pattern
        });
      }
      this.deps.audit.recordAccess(this.deps.ctx, {
        intent: "glob",
        absolute: this.deps.primaryWorkspace,
        durationMs: performance.now() - start,
        sizeBytes: out.length,
        pattern
      });
      return out;
    } catch (err) {
      throw this.recordAndWrap(err, "glob", pattern);
    }
  }
  async writeTextAtomic(p, content, opts) {
    const start = performance.now();
    try {
      assertTrustedForIntent(this.deps.trusted, "write");
      validateWriteTextAtomicOptions(opts);
      const decodedSizeBytes = Buffer.byteLength(content, "utf-8");
      enforceWriteSize(decodedSizeBytes);
      const out = await this.deps.pathLocks.runExclusive(
        p,
        async () => {
          const existingMeta = opts.mode === "replace" ? await readExistingTextMeta(p, opts.expectedHash) : void 0;
          if (opts.mode === "create") {
            await assertCreateTargetAbsent(p);
          }
          const meta = mergeWriteMeta(existingMeta, opts);
          const result = await atomicWriteTextResolvedFile({
            target: p,
            content,
            mode: opts.mode,
            expectedHash: opts.expectedHash,
            meta
          });
          const verdict = this.ignoreVerdict(p, "file");
          if (verdict.ignored) meta.matchedIgnore = verdict.category;
          meta.sizeBytes = result.sizeBytes;
          meta.hash = result.hash;
          this.deps.audit.recordAccess(this.deps.ctx, {
            intent: "write",
            absolute: p,
            durationMs: performance.now() - start,
            sizeBytes: result.sizeBytes,
            matchedIgnore: meta.matchedIgnore
          });
          return {
            created: opts.mode === "create",
            sizeBytes: result.sizeBytes,
            hash: result.hash,
            meta
          };
        }
      );
      return out;
    } catch (err) {
      throw this.recordAndWrap(err, "write", p);
    }
  }
  async writeTextOverwrite(p, content, opts = {}) {
    const start = performance.now();
    try {
      assertTrustedForIntent(this.deps.trusted, "write");
      const decodedSizeBytes = Buffer.byteLength(content, "utf-8");
      enforceWriteSize(decodedSizeBytes);
      const out = await this.deps.pathLocks.runExclusive(
        p,
        async () => {
          let targetExisted = false;
          try {
            await fsp2.lstat(p);
            targetExisted = true;
          } catch (err) {
            if (err?.code !== "ENOENT") {
              throw err;
            }
          }
          let existingMeta;
          try {
            existingMeta = await readExistingTextMeta(p);
          } catch (err) {
            const code = err?.code;
            const kind = err?.kind;
            if (code !== "ENOENT" && code !== "EACCES" && code !== "EPERM" && kind !== "file_too_large" && kind !== "binary_file") {
              throw err;
            }
          }
          const meta = mergeWriteMeta(existingMeta, opts);
          const result = await atomicWriteTextResolvedFile({
            target: p,
            content,
            mode: "overwrite",
            meta
          });
          const verdict = this.ignoreVerdict(p, "file");
          if (verdict.ignored) meta.matchedIgnore = verdict.category;
          meta.sizeBytes = result.sizeBytes;
          meta.hash = result.hash;
          this.deps.audit.recordAccess(this.deps.ctx, {
            intent: "write",
            absolute: p,
            durationMs: performance.now() - start,
            sizeBytes: result.sizeBytes,
            matchedIgnore: meta.matchedIgnore
          });
          return {
            created: !targetExisted,
            sizeBytes: result.sizeBytes,
            hash: result.hash,
            meta
          };
        }
      );
      return out;
    } catch (err) {
      throw this.recordAndWrap(err, "write", p);
    }
  }
  async writeText(p, content, opts) {
    const start = performance.now();
    try {
      assertTrustedForIntent(this.deps.trusted, "write");
      const sizeBytes = Buffer.byteLength(content, "utf-8");
      enforceWriteSize(sizeBytes);
      await assertNotSymlinkBeforeWrite(p);
      await this.deps.lowFs.writeTextFile({
        path: p,
        content,
        _meta: opts ? buildWriteMeta(opts) : void 0
      });
      const verdict = this.ignoreVerdict(p, "file");
      this.deps.audit.recordAccess(this.deps.ctx, {
        intent: "write",
        absolute: p,
        durationMs: performance.now() - start,
        sizeBytes,
        matchedIgnore: verdict.ignored ? verdict.category : void 0
      });
    } catch (err) {
      throw this.recordAndWrap(err, "write", p);
    }
  }
  async editAtomic(p, oldText, newText, opts) {
    const start = performance.now();
    try {
      assertTrustedForIntent(this.deps.trusted, "edit");
      if (!isContentHash(opts.expectedHash)) {
        throw new FsError(
          "parse_error",
          "expectedHash must match sha256:<64 lowercase hex chars>"
        );
      }
      if (typeof oldText !== "string" || oldText.length === 0) {
        throw new FsError(
          "parse_error",
          `oldText must be a non-empty string for edit on ${p}`
        );
      }
      if (typeof newText !== "string") {
        throw new FsError("parse_error", "newText must be a string");
      }
      const out = await this.deps.pathLocks.runExclusive(
        p,
        async () => {
          const snapshot = await readTextSnapshotFromResolvedFile(p);
          if (snapshot.meta.hash !== opts.expectedHash) {
            throw new FsError(
              "hash_mismatch",
              `expected ${opts.expectedHash}, found ${snapshot.meta.hash}`,
              { hint: "re-read the file and retry with the latest hash" }
            );
          }
          const current = snapshot.content;
          const occurrences = countOccurrences(current, oldText);
          if (occurrences === 0) {
            const snippet = oldText.length > 80 ? oldText.slice(0, 80) + "..." : oldText;
            throw new FsError("text_not_found", `oldText not found in ${p}`, {
              hint: `searched for: ${JSON.stringify(snippet)}`
            });
          }
          if (occurrences > 1) {
            throw new FsError(
              "ambiguous_text_match",
              `oldText appears ${occurrences} times in ${p}`,
              {
                hint: "pass a larger oldText span that occurs exactly once"
              }
            );
          }
          const idx = current.indexOf(oldText);
          const next = current.slice(0, idx) + newText + current.slice(idx + oldText.length);
          enforceWriteSize(Buffer.byteLength(next, "utf-8"));
          const meta = mergeWriteMeta(snapshot.meta, {});
          const result = await atomicWriteTextResolvedFile({
            target: p,
            content: next,
            mode: "replace",
            expectedHash: opts.expectedHash,
            meta
          });
          const verdict = this.ignoreVerdict(p, "file");
          if (verdict.ignored) meta.matchedIgnore = verdict.category;
          meta.sizeBytes = result.sizeBytes;
          meta.hash = result.hash;
          this.deps.audit.recordAccess(this.deps.ctx, {
            intent: "edit",
            absolute: p,
            durationMs: performance.now() - start,
            sizeBytes: result.sizeBytes,
            matchedIgnore: meta.matchedIgnore
          });
          return {
            writtenBytes: result.sizeBytes,
            hash: result.hash,
            meta
          };
        }
      );
      return out;
    } catch (err) {
      throw this.recordAndWrap(err, "edit", p);
    }
  }
  async edit(p, oldText, newText, opts) {
    if (opts?.expectedHash !== void 0) {
      return this.editAtomic(p, oldText, newText, {
        expectedHash: opts.expectedHash
      });
    }
    const start = performance.now();
    try {
      assertTrustedForIntent(this.deps.trusted, "edit");
      const st = await fsp2.stat(p);
      if (st.size > MAX_READ_BYTES) {
        throw new FsError(
          "file_too_large",
          `file of ${st.size} bytes exceeds edit cap of ${MAX_READ_BYTES} bytes`,
          {
            hint: "split large edits into bounded readBytes/writeText sequences"
          }
        );
      }
      if (await detectBinary(p)) {
        throw new FsError("binary_file", `cannot edit binary file: ${p}`, {
          hint: "edit() works on text files only"
        });
      }
      if (oldText.length === 0) {
        throw new FsError(
          "parse_error",
          `oldText must be a non-empty string for edit on ${p}`,
          {
            hint: "empty oldText would match at position 0 and silently prepend newText"
          }
        );
      }
      const readResult = await this.deps.lowFs.readTextFile({
        path: p,
        limit: Number.POSITIVE_INFINITY,
        line: 0
      });
      const current = readResult.content;
      await assertInodeStableAfterRead(p, st.ino);
      const idx = current.indexOf(oldText);
      if (idx === -1) {
        const snippet = oldText.length > 80 ? oldText.slice(0, 80) + "\u2026" : oldText;
        throw new FsError("parse_error", `oldText not found in ${p}`, {
          hint: `edit() expects oldText to appear verbatim; searched for: ${JSON.stringify(snippet)}`
        });
      }
      const next = current.slice(0, idx) + newText + current.slice(idx + oldText.length);
      const writtenBytes = Buffer.byteLength(next, "utf-8");
      enforceWriteSize(writtenBytes);
      await assertNotSymlinkBeforeWrite(p);
      await this.deps.lowFs.writeTextFile({
        path: p,
        content: next,
        _meta: readResult._meta
      });
      const editVerdict = this.ignoreVerdict(p, "file");
      this.deps.audit.recordAccess(this.deps.ctx, {
        intent: "edit",
        absolute: p,
        durationMs: performance.now() - start,
        sizeBytes: writtenBytes,
        matchedIgnore: editVerdict.ignored ? editVerdict.category : void 0
      });
      return { writtenBytes };
    } catch (err) {
      throw this.recordAndWrap(err, "edit", p);
    }
  }
  /**
   * Coerce an arbitrary thrown value into an `FsError`, emit the
   * matching `fs.denied` audit event, and return the typed error
   * for the caller to rethrow. Body methods invoke this in their
   * `catch` so:
   *   - raw fs errnos (`EACCES`, `ENOTDIR`, …) get categorized
   *     instead of escaping as opaque 5xx,
   *   - the audit log records every failure (the prior helper
   *     early-returned for non-`FsError`s and silently lost the
   *     event), and
   *   - routes can still rely on `instanceof FsError`
   *     for their `sendFsError` serializer.
   */
  recordAndWrap(err, intent, input) {
    const fs3 = wrapAsFsError(err);
    this.deps.audit.recordDenied(this.deps.ctx, {
      intent,
      input,
      errorKind: fs3.kind,
      hint: fs3.hint,
      // Quote the underlying OS / FsError message so audit
      // consumers debugging a production incident can see the
      // actual cause (errno text, byte counts, glob pattern,
      // etc.) rather than just `errorKind` + `hint`.
      message: fs3.message,
      // For glob denials (parse_error pattern rejection,
      // catastrophic walk failures) the input IS the pattern
      // already; surfacing it on the dedicated `pattern` field
      // keeps the schema parallel with successful `recordAccess`
      // glob rows so consumers can `data.pattern` without
      // branching on intent.
      pattern: intent === "glob" ? input : void 0
    });
    return fs3;
  }
};
var CONTENT_HASH_RE = /^sha256:[0-9a-f]{64}$/;
function isContentHash(value) {
  return typeof value === "string" && CONTENT_HASH_RE.test(value);
}
__name(isContentHash, "isContentHash");
function validateWriteTextAtomicOptions(opts) {
  if (opts.mode !== "create" && opts.mode !== "replace") {
    throw new FsError(
      "parse_error",
      'mode must be either "create" or "replace" (use writeTextOverwrite() for unconditional overwrites)'
    );
  }
  if (opts.expectedHash !== void 0 && !isContentHash(opts.expectedHash)) {
    throw new FsError(
      "parse_error",
      "expectedHash must match sha256:<64 lowercase hex chars>"
    );
  }
  if (opts.mode === "replace" && opts.expectedHash === void 0) {
    throw new FsError(
      "parse_error",
      'expectedHash is required when mode is "replace"'
    );
  }
  if (opts.lineEnding !== void 0 && opts.lineEnding !== "lf" && opts.lineEnding !== "crlf") {
    throw new FsError("parse_error", 'lineEnding must be "lf" or "crlf"');
  }
}
__name(validateWriteTextAtomicOptions, "validateWriteTextAtomicOptions");
async function readTextSnapshotFromResolvedFile(p, opts = {}) {
  const pre = await fsp2.lstat(p);
  if (pre.isSymbolicLink()) {
    throw new FsError("symlink_escape", `path is a symlink: ${p}`, {
      hint: "re-resolve the target file instead of reading through a link"
    });
  }
  if (!pre.isFile()) {
    throw new FsError("parse_error", `path is not a regular file: ${p}`);
  }
  if (pre.size > MAX_READ_BYTES) {
    throw new FsError(
      "file_too_large",
      `file of ${pre.size} bytes exceeds read cap of ${MAX_READ_BYTES} bytes`,
      {
        hint: "use readBytes for explicit byte-windowed access on large files"
      }
    );
  }
  const raw = await readStableRegularFileBuffer(p, pre);
  if (looksBinary(raw)) {
    throw new FsError("binary_file", `binary file: ${p}`, {
      hint: "use readBytes for binary content"
    });
  }
  const decoded = decodeBufferWithEncodingInfo(raw);
  const startLineIndex = opts.line !== void 0 ? opts.line - 1 : 0;
  const sliced = sliceDecodedText(
    decoded.content,
    startLineIndex,
    opts.limit ?? Number.POSITIVE_INFINITY
  );
  const sizeOutcome = enforceReadSize(raw.length, opts.maxBytes);
  let content = sliced.content;
  const meta = {
    encoding: decoded.encoding,
    bom: decoded.bom,
    lineEnding: detectLineEnding(content),
    sizeBytes: raw.length,
    originalLineCount: sliced.originalLineCount,
    hash: hashBuffer(raw)
  };
  if (sizeOutcome.truncated) {
    const buf = Buffer.from(content, "utf-8");
    if (buf.length > sizeOutcome.bytesToRead) {
      content = safeUtf8Truncate(buf, sizeOutcome.bytesToRead).toString(
        "utf-8"
      );
      meta.lineEnding = detectLineEnding(content);
    }
    meta.truncated = true;
  }
  if (opts.limit !== void 0 && Number.isFinite(opts.limit) && sliced.originalLineCount > opts.limit + startLineIndex) {
    meta.truncated = true;
  }
  return { content, meta };
}
__name(readTextSnapshotFromResolvedFile, "readTextSnapshotFromResolvedFile");
async function readStableRegularFileBuffer(p, pre) {
  const fh = await fsp2.open(p, "r");
  let opened;
  try {
    opened = await fh.stat();
    assertSameFile(pre, opened, p, "read");
    if (opened.size > MAX_READ_BYTES) {
      throw new FsError(
        "file_too_large",
        `file of ${opened.size} bytes exceeds read cap of ${MAX_READ_BYTES} bytes`,
        {
          hint: "use readBytes for explicit byte-windowed access on large files"
        }
      );
    }
    const out = Buffer.alloc(opened.size);
    let offset = 0;
    while (offset < opened.size) {
      const read = await fh.read(out, offset, opened.size - offset, offset);
      if (read.bytesRead === 0) break;
      offset += read.bytesRead;
    }
    const afterRead = await fh.stat();
    assertSameFile(opened, afterRead, p, "read");
    if (afterRead.size !== opened.size || afterRead.mtimeMs !== opened.mtimeMs) {
      throw new FsError("hash_mismatch", `file changed during read: ${p}`, {
        hint: "retry after re-reading the latest file hash"
      });
    }
    const post = await fsp2.lstat(p);
    assertSameFile(pre, post, p, "read");
    if (post.size !== opened.size || post.mtimeMs !== opened.mtimeMs) {
      throw new FsError("hash_mismatch", `file changed during read: ${p}`, {
        hint: "retry after re-reading the latest file hash"
      });
    }
    return offset === out.length ? out : out.subarray(0, offset);
  } finally {
    await fh.close();
  }
}
__name(readStableRegularFileBuffer, "readStableRegularFileBuffer");
function sliceDecodedText(content, startLine, limit) {
  const lines = content.split("\n");
  const originalLineCount = lines.length;
  const endLine = Math.min(startLine + limit, originalLineCount);
  const actualStartLine = Math.min(startLine, originalLineCount);
  return {
    content: lines.slice(actualStartLine, endLine).join("\n"),
    originalLineCount
  };
}
__name(sliceDecodedText, "sliceDecodedText");
function looksBinary(buf) {
  if (buf.length === 0) return false;
  const bomProbe = buf.subarray(0, Math.min(4, buf.length));
  const hasUnicodeBom = bomProbe.length >= 4 && (bomProbe[0] === 255 && bomProbe[1] === 254 && bomProbe[2] === 0 && bomProbe[3] === 0 || bomProbe[0] === 0 && bomProbe[1] === 0 && bomProbe[2] === 254 && bomProbe[3] === 255) || bomProbe.length >= 3 && bomProbe[0] === 239 && bomProbe[1] === 187 && bomProbe[2] === 191 || bomProbe.length >= 2 && (bomProbe[0] === 255 && bomProbe[1] === 254 || bomProbe[0] === 254 && bomProbe[1] === 255);
  if (hasUnicodeBom) return false;
  const sampleLength = Math.min(4096, buf.length);
  let nonPrintableCount = 0;
  for (let i = 0; i < sampleLength; i++) {
    if (buf[i] === 0) return true;
    if (buf[i] < 9 || buf[i] > 13 && buf[i] < 32) {
      nonPrintableCount++;
    }
  }
  return nonPrintableCount / sampleLength > 0.3;
}
__name(looksBinary, "looksBinary");
async function readExistingTextMeta(p, expectedHash) {
  const snapshot = await readTextSnapshotFromResolvedFile(p);
  if (expectedHash !== void 0 && snapshot.meta.hash !== expectedHash) {
    throw new FsError(
      "hash_mismatch",
      `expected ${expectedHash}, found ${snapshot.meta.hash}`,
      { hint: "re-read the file and retry with the latest hash" }
    );
  }
  return snapshot.meta;
}
__name(readExistingTextMeta, "readExistingTextMeta");
function mergeWriteMeta(existing, opts) {
  return {
    encoding: opts.encoding ?? existing?.encoding ?? "utf-8",
    bom: opts.bom ?? existing?.bom ?? false,
    lineEnding: opts.lineEnding ?? existing?.lineEnding ?? "lf"
  };
}
__name(mergeWriteMeta, "mergeWriteMeta");
async function atomicWriteTextResolvedFile(input) {
  const target = input.target;
  const parent = path4.dirname(target);
  const parentStat = await fsp2.lstat(parent);
  if (parentStat.isSymbolicLink()) {
    throw new FsError("symlink_escape", `parent path is a symlink: ${parent}`, {
      hint: "re-resolve the target after detecting parent-symlink swaps"
    });
  }
  if (!parentStat.isDirectory()) {
    throw new FsError(
      "parse_error",
      `parent path is not a directory: ${parent}`
    );
  }
  const tmpPath = path4.join(
    parent,
    `.${path4.basename(target)}.${process.pid}.${randomBytes(6).toString("hex")}.tmp`
  );
  let tempLive = false;
  let tempHandle;
  let tempStat;
  try {
    tempHandle = await reserveTempFile(tmpPath);
    tempLive = true;
    const encoded = await writeEncodedTextTemp({
      targetPath: target,
      tmpPath,
      content: input.content,
      meta: input.meta,
      handle: tempHandle
    });
    tempStat = encoded.stat;
    const targetState = await assertAtomicTargetPrecondition({
      target,
      mode: input.mode,
      expectedHash: input.expectedHash
    });
    await chmodHandleBestEffort(tempHandle, targetState.mode ?? 384);
    await assertTempPathMatchesStat(tmpPath, tempStat);
    await tempHandle.close();
    tempHandle = void 0;
    await assertTempPathMatchesStat(tmpPath, tempStat);
    if (input.mode === "create") {
      await publishCreateNoClobber(tmpPath, target);
    } else {
      await renameWithRetryLocal(tmpPath, target, 3, 50);
    }
    tempLive = false;
    await fsyncParentDirBestEffort(parent);
    return encoded;
  } catch (err) {
    await tempHandle?.close().catch(() => void 0);
    if (tempLive) {
      try {
        await fsp2.unlink(tmpPath);
      } catch {
      }
    }
    throw err;
  }
}
__name(atomicWriteTextResolvedFile, "atomicWriteTextResolvedFile");
async function reserveTempFile(tmpPath) {
  return fsp2.open(tmpPath, "wx", 384);
}
__name(reserveTempFile, "reserveTempFile");
async function writeEncodedTextTemp(input) {
  const buf = encodeTextFileContent(
    input.targetPath,
    input.content,
    buildWriteMeta(input.meta)
  );
  enforceWriteSize(buf.length);
  await input.handle.writeFile(buf);
  await syncHandleBestEffort(input.handle);
  const st = await fsp2.lstat(input.tmpPath);
  const opened = await input.handle.stat();
  assertSameFile(opened, st, input.tmpPath, "write");
  if (st.isSymbolicLink()) {
    throw new FsError(
      "symlink_escape",
      `temporary path became a symlink: ${input.tmpPath}`,
      { hint: "temp-file race detected before final rename" }
    );
  }
  if (!st.isFile()) {
    throw new FsError(
      "parse_error",
      `temporary path is not a regular file: ${input.tmpPath}`
    );
  }
  return { sizeBytes: buf.length, hash: hashBuffer(buf), stat: st };
}
__name(writeEncodedTextTemp, "writeEncodedTextTemp");
async function assertCreateTargetAbsent(target) {
  try {
    const st = await fsp2.lstat(target);
    if (st.isSymbolicLink()) {
      throw new FsError(
        "symlink_escape",
        `path is a symlink and cannot be created over: ${target}`,
        { hint: "remove the symlink or resolve the target explicitly" }
      );
    }
    throw new FsError("file_already_exists", `file already exists: ${target}`);
  } catch (err) {
    const code = err?.code;
    if (code === "ENOENT") return;
    throw err;
  }
}
__name(assertCreateTargetAbsent, "assertCreateTargetAbsent");
async function assertAtomicTargetPrecondition(input) {
  if (input.mode === "create") {
    await assertCreateTargetAbsent(input.target);
    return {};
  }
  if (input.mode === "overwrite") {
    let pre2;
    try {
      pre2 = await fsp2.lstat(input.target);
    } catch (err) {
      if (err?.code === "ENOENT") {
        return {};
      }
      throw err;
    }
    if (pre2.isSymbolicLink()) {
      throw new FsError(
        "symlink_escape",
        `path is a symlink and cannot be overwritten atomically: ${input.target}`,
        {
          hint: "re-resolve the target file instead of writing through a link"
        }
      );
    }
    if (!pre2.isFile()) {
      throw new FsError(
        "parse_error",
        `path is not a regular file: ${input.target}`
      );
    }
    return { mode: pre2.mode & 4095 };
  }
  if (!isContentHash(input.expectedHash)) {
    throw new FsError(
      "parse_error",
      'expectedHash is required when mode is "replace"'
    );
  }
  const pre = await fsp2.lstat(input.target);
  if (pre.isSymbolicLink()) {
    throw new FsError(
      "symlink_escape",
      `path is a symlink and cannot be replaced atomically: ${input.target}`,
      { hint: "re-resolve the target file instead of writing through a link" }
    );
  }
  if (!pre.isFile()) {
    throw new FsError(
      "parse_error",
      `path is not a regular file: ${input.target}`
    );
  }
  const actual = await hashRegularFileAtPath(input.target, pre);
  if (actual !== input.expectedHash) {
    throw new FsError(
      "hash_mismatch",
      `expected ${input.expectedHash}, found ${actual}`,
      { hint: "re-read the file and retry with the latest hash" }
    );
  }
  return { mode: pre.mode & 4095 };
}
__name(assertAtomicTargetPrecondition, "assertAtomicTargetPrecondition");
async function hashRegularFileAtPath(p, pre) {
  const fh = await fsp2.open(p, "r");
  const hash = createHash2("sha256");
  let opened;
  try {
    opened = await fh.stat();
    assertSameFile(pre, opened, p, "read");
    const buf = Buffer.allocUnsafe(64 * 1024);
    let offset = 0;
    while (offset < opened.size) {
      const read = await fh.read(
        buf,
        0,
        Math.min(buf.length, opened.size - offset),
        offset
      );
      if (read.bytesRead === 0) break;
      hash.update(buf.subarray(0, read.bytesRead));
      offset += read.bytesRead;
    }
  } finally {
    await fh.close();
  }
  if (opened === void 0) {
    throw new FsError("internal_error", `failed to stat opened file: ${p}`);
  }
  const post = await fsp2.lstat(p);
  assertSameFile(pre, post, p, "read");
  if (post.size !== opened.size || post.mtimeMs !== opened.mtimeMs) {
    throw new FsError("hash_mismatch", `file changed during hash: ${p}`, {
      hint: "retry after re-reading the latest file hash"
    });
  }
  return `sha256:${hash.digest("hex")}`;
}
__name(hashRegularFileAtPath, "hashRegularFileAtPath");
function hashBuffer(buf) {
  return `sha256:${createHash2("sha256").update(buf).digest("hex")}`;
}
__name(hashBuffer, "hashBuffer");
function assertSameFile(pre, post, p, intent) {
  const preDev = toBigInt(pre.dev);
  const postDev = toBigInt(post.dev);
  const preIno = toBigInt(pre.ino);
  const postIno = toBigInt(post.ino);
  if (preDev !== 0n && postDev !== 0n && preIno !== 0n && postIno !== 0n && (preDev !== postDev || preIno !== postIno)) {
    throw new FsError("symlink_escape", `path changed during ${intent}: ${p}`, {
      hint: "TOCTOU swap detected via device/inode comparison"
    });
  }
}
__name(assertSameFile, "assertSameFile");
function toBigInt(value) {
  return typeof value === "bigint" ? value : BigInt(value);
}
__name(toBigInt, "toBigInt");
async function syncHandleBestEffort(fh) {
  try {
    await fh.sync();
  } catch {
  }
}
__name(syncHandleBestEffort, "syncHandleBestEffort");
async function fsyncParentDirBestEffort(parent) {
  let fh;
  try {
    fh = await fsp2.open(parent, "r");
    await fh.sync();
  } catch {
  } finally {
    await fh?.close().catch(() => void 0);
  }
}
__name(fsyncParentDirBestEffort, "fsyncParentDirBestEffort");
async function chmodHandleBestEffort(fh, mode) {
  try {
    await fh.chmod(mode);
  } catch {
  }
}
__name(chmodHandleBestEffort, "chmodHandleBestEffort");
async function assertTempPathMatchesStat(tmpPath, expected) {
  const st = await fsp2.lstat(tmpPath);
  if (st.isSymbolicLink()) {
    throw new FsError(
      "symlink_escape",
      `temporary path is a symlink: ${tmpPath}`,
      {
        hint: "temp-file race detected before final rename"
      }
    );
  }
  if (!st.isFile()) {
    throw new FsError(
      "parse_error",
      `temporary path is not a regular file: ${tmpPath}`
    );
  }
  assertSameFile(expected, st, tmpPath, "write");
}
__name(assertTempPathMatchesStat, "assertTempPathMatchesStat");
async function publishCreateNoClobber(tmpPath, target) {
  try {
    await fsp2.link(tmpPath, target);
  } catch (err) {
    const code = err?.code;
    if (code === "EEXIST") {
      throw new FsError(
        "file_already_exists",
        `file already exists: ${target}`
      );
    }
    throw err;
  }
  await fsp2.unlink(tmpPath).catch(() => void 0);
}
__name(publishCreateNoClobber, "publishCreateNoClobber");
async function renameWithRetryLocal(src, dest, retries, delayMs) {
  for (let attempt = 0; attempt <= retries; attempt++) {
    try {
      await fsp2.rename(src, dest);
      return;
    } catch (err) {
      const code = err?.code;
      const retryable = code === "EPERM" || code === "EACCES";
      if (!retryable || attempt === retries) throw err;
      await new Promise(
        (resolve5) => setTimeout(resolve5, delayMs * 2 ** attempt)
      );
    }
  }
}
__name(renameWithRetryLocal, "renameWithRetryLocal");
function countOccurrences(haystack, needle) {
  let count = 0;
  let index = 0;
  while (true) {
    const found = haystack.indexOf(needle, index);
    if (found === -1) return count;
    count += 1;
    index = found + needle.length;
  }
}
__name(countOccurrences, "countOccurrences");
function safeUtf8Truncate(buf, maxBytes) {
  if (buf.length <= maxBytes) return buf;
  let end = maxBytes;
  while (end > 0 && (buf[end] & 192) === 128) end--;
  return buf.subarray(0, end);
}
__name(safeUtf8Truncate, "safeUtf8Truncate");
async function assertInodeStableAfterRead(p, preIno) {
  const post = await fsp2.lstat(p);
  if (post.isSymbolicLink()) {
    throw new FsError(
      "symlink_escape",
      `path was replaced with a symlink during read: ${p}`,
      { hint: "TOCTOU swap detected via post-read lstat" }
    );
  }
  const preNum = toBigInt(preIno);
  const postNum = toBigInt(post.ino);
  if (preNum !== 0n && postNum !== 0n && preNum !== postNum) {
    throw new FsError(
      "symlink_escape",
      `path inode changed during read: ${p}`,
      { hint: "TOCTOU swap detected via inode comparison" }
    );
  }
}
__name(assertInodeStableAfterRead, "assertInodeStableAfterRead");
async function assertNotSymlinkBeforeWrite(p) {
  let pre;
  try {
    pre = await fsp2.lstat(p);
  } catch (err) {
    const code = err?.code;
    if (code === "ENOENT") return;
    throw err;
  }
  if (pre.isSymbolicLink()) {
    throw new FsError(
      "symlink_escape",
      `path was replaced with a symlink before write: ${p}`,
      {
        hint: "TOCTOU swap detected via pre-write lstat \u2014 re-resolve before retrying"
      }
    );
  }
}
__name(assertNotSymlinkBeforeWrite, "assertNotSymlinkBeforeWrite");
function kindFromStatLike(s) {
  if (s.isSymbolicLink()) return "symlink";
  if (s.isDirectory()) return "directory";
  if (s.isFile()) return "file";
  return "other";
}
__name(kindFromStatLike, "kindFromStatLike");
function errorCode(err) {
  return err?.code;
}
__name(errorCode, "errorCode");
function errorKindForRealpathFailure(err) {
  const code = errorCode(err);
  if (code === "EACCES" || code === "EPERM") return "permission_denied";
  if (code === "ENOENT" || code === "ELOOP") return "symlink_escape";
  return "io_error";
}
__name(errorKindForRealpathFailure, "errorKindForRealpathFailure");
function buildWriteMeta(opts) {
  const meta = {};
  if (opts.bom !== void 0) meta["bom"] = opts.bom;
  if (opts.encoding) meta["encoding"] = opts.encoding;
  if (opts.lineEnding) meta["lineEnding"] = opts.lineEnding;
  return Object.keys(meta).length > 0 ? meta : void 0;
}
__name(buildWriteMeta, "buildWriteMeta");

// packages/cli/src/serve/routes/workspace-setup-github.ts
init_esbuild_shims();
import { promises as fsp3 } from "node:fs";
import * as path7 from "node:path";

// packages/cli/src/serve/routes/workspace-file-read.ts
init_esbuild_shims();
import * as path6 from "node:path";

// packages/cli/src/serve/workspace-route-runtime.ts
init_esbuild_shims();
import path5 from "node:path";
function isPortableAbsolutePath(value) {
  return path5.isAbsolute(value) || /^[A-Za-z]:[\\/]/.test(value) || /^\\\\[^\\]+\\[^\\]+/.test(value);
}
__name(isPortableAbsolutePath, "isPortableAbsolutePath");
function isUncPath(value) {
  return /^\\\\[^\\]+\\[^\\]+/.test(value);
}
__name(isUncPath, "isUncPath");
function normalizePortableAbsolutePath(value) {
  if (/^[A-Za-z]:[\\/]/.test(value) || /^\\\\[^\\]+\\[^\\]+/.test(value)) {
    return path5.win32.normalize(value).toLowerCase();
  }
  return path5.resolve(value);
}
__name(normalizePortableAbsolutePath, "normalizePortableAbsolutePath");
function resolveRegisteredWorkspaceRuntimeByPathSelector(registry, selector) {
  const exact = registry.getByWorkspaceCwd(selector);
  if (exact) return exact;
  if (path5.isAbsolute(selector) && !isUncPath(selector)) {
    try {
      const canonicalSelector = canonicalizeWorkspace(selector);
      const canonicalMatch = registry.getByWorkspaceCwd(canonicalSelector);
      if (canonicalMatch) return canonicalMatch;
      for (const runtime of registry.list()) {
        if (canonicalizeWorkspace(runtime.workspaceCwd) === canonicalSelector) {
          return runtime;
        }
      }
    } catch {
    }
  }
  const normalizedSelector = normalizePortableAbsolutePath(selector);
  return registry.list().find(
    (runtime) => normalizePortableAbsolutePath(runtime.workspaceCwd) === normalizedSelector
  );
}
__name(resolveRegisteredWorkspaceRuntimeByPathSelector, "resolveRegisteredWorkspaceRuntimeByPathSelector");
function resolveManagedWorkspaceRuntimeByPathSelector(registry, selector) {
  const exact = registry.getManagedByWorkspaceCwd(selector);
  if (exact) return exact;
  if (path5.isAbsolute(selector) && !isUncPath(selector)) {
    try {
      const canonicalSelector = canonicalizeWorkspace(selector);
      const canonicalMatch = registry.getManagedByWorkspaceCwd(canonicalSelector);
      if (canonicalMatch) return canonicalMatch;
      for (const runtime of registry.listManaged()) {
        if (canonicalizeWorkspace(runtime.workspaceCwd) === canonicalSelector) {
          return runtime;
        }
      }
    } catch {
    }
  }
  const normalizedSelector = normalizePortableAbsolutePath(selector);
  return registry.listManaged().find(
    (runtime) => normalizePortableAbsolutePath(runtime.workspaceCwd) === normalizedSelector
  );
}
__name(resolveManagedWorkspaceRuntimeByPathSelector, "resolveManagedWorkspaceRuntimeByPathSelector");
function resolveWorkspaceRuntimeFromParam(registry, req, res, paramName = "workspace") {
  const selector = req.params[paramName] ?? "";
  const byId = registry.getByWorkspaceId(selector);
  if (byId) return byId;
  if (!isPortableAbsolutePath(selector)) {
    res.status(400).json({
      error: `\`:${paramName}\` must decode to a workspace id or absolute path`,
      code: "workspace_mismatch"
    });
    return null;
  }
  const runtime = resolveRegisteredWorkspaceRuntimeByPathSelector(
    registry,
    selector
  );
  if (!runtime) {
    sendWorkspaceMismatch(res, registry);
    return null;
  }
  return runtime;
}
__name(resolveWorkspaceRuntimeFromParam, "resolveWorkspaceRuntimeFromParam");
function resolveManagedWorkspaceRuntimeFromParam(registry, req, res, paramName = "workspace") {
  const selector = req.params[paramName] ?? "";
  const byId = registry.getManagedByWorkspaceId(selector);
  if (byId) return byId;
  if (!isPortableAbsolutePath(selector)) {
    res.status(400).json({
      error: `\`:${paramName}\` must decode to a workspace id or absolute path`,
      code: "workspace_mismatch"
    });
    return null;
  }
  const runtime = resolveManagedWorkspaceRuntimeByPathSelector(
    registry,
    selector
  );
  if (!runtime) {
    res.status(400).json({
      error: "Workspace mismatch: the requested workspace is not registered with this daemon.",
      code: "workspace_mismatch"
    });
    return null;
  }
  return runtime;
}
__name(resolveManagedWorkspaceRuntimeFromParam, "resolveManagedWorkspaceRuntimeFromParam");
function requireTrustedWorkspaceRuntime(runtime, res) {
  if (runtime.trusted) return true;
  sendUntrustedWorkspaceResponse(res);
  return false;
}
__name(requireTrustedWorkspaceRuntime, "requireTrustedWorkspaceRuntime");
function sendUntrustedWorkspaceResponse(res, extra) {
  res.status(403).json({
    error: "Workspace is not trusted.",
    code: "untrusted_workspace",
    ...extra
  });
}
__name(sendUntrustedWorkspaceResponse, "sendUntrustedWorkspaceResponse");
function getWorkspaceRouteContext(req) {
  return req.workspaceRouteContext;
}
__name(getWorkspaceRouteContext, "getWorkspaceRouteContext");
function setWorkspaceRouteContext(req, context) {
  req.workspaceRouteContext = context;
}
__name(setWorkspaceRouteContext, "setWorkspaceRouteContext");
function sendWorkspaceMismatch(res, registry) {
  const runtimes = registry.list();
  res.status(400).json({
    error: "Workspace mismatch: the requested workspace is not registered with this daemon.",
    code: "workspace_mismatch",
    workspaceCount: runtimes.length
  });
}
__name(sendWorkspaceMismatch, "sendWorkspaceMismatch");

// packages/cli/src/serve/routes/workspace-file-read.ts
var MAX_LIST_ENTRIES = 2e3;
var MAX_FILE_LINE_LIMIT = 2e3;
var DEFAULT_FILE_BYTES_MAX_BYTES = 64 * 1024;
var DEFAULT_GLOB_MAX_RESULTS = 5e3;
var MAX_GLOB_MAX_RESULTS = 5e4;
function applyReadHeaders(res) {
  res.set("Cache-Control", "no-store");
  res.set("X-Content-Type-Options", "nosniff");
}
__name(applyReadHeaders, "applyReadHeaders");
function sendFsError(res, err, route) {
  applyReadHeaders(res);
  if (isFsError(err)) {
    const fs3 = err;
    res.status(fs3.status).json({
      errorKind: fs3.kind,
      error: fs3.message,
      hint: fs3.hint,
      status: fs3.status
    });
    return;
  }
  writeStderrLine(
    `qwen serve: ${route} unexpected error: ${err instanceof Error ? err.message : String(err)}`
  );
  res.status(500).json({
    errorKind: "internal_error",
    error: err instanceof Error ? err.message : String(err),
    status: 500
  });
}
__name(sendFsError, "sendFsError");
function parseIntInRange(raw, min, max) {
  if (raw === void 0) return void 0;
  if (typeof raw !== "string" || !/^\d+$/.test(raw)) return null;
  const n = Number.parseInt(raw, 10);
  if (!Number.isSafeInteger(n) || n < min || n > max) return null;
  return n;
}
__name(parseIntInRange, "parseIntInRange");
function parseBoolFlag(raw) {
  return raw === "1" || raw === "true";
}
__name(parseBoolFlag, "parseBoolFlag");
function requireStringQuery(res, raw, name, route) {
  if (typeof raw !== "string" || raw.length === 0) {
    applyReadHeaders(res);
    res.status(400).json({
      errorKind: "parse_error",
      error: `${name} query parameter is required`,
      status: 400
    });
    writeStderrLine(
      `qwen serve: ${route} rejected request missing required ?${name}`
    );
    return null;
  }
  return raw;
}
__name(requireStringQuery, "requireStringQuery");
function routeName(req, legacyRoute) {
  const context = getWorkspaceRouteContext(req);
  if (!context) return legacyRoute;
  return `${context.routePrefix}${legacyRoute.slice("GET ".length)}`;
}
__name(routeName, "routeName");
function getFsFactory(req, res) {
  const context = getWorkspaceRouteContext(req);
  if (context) return context.runtime.routeFileSystemFactory;
  const factory = req.app.locals.fsFactory;
  if (!factory) {
    applyReadHeaders(res);
    res.status(500).json({
      errorKind: "internal_error",
      error: "workspace filesystem factory is not configured",
      status: 500
    });
    return null;
  }
  return factory;
}
__name(getFsFactory, "getFsFactory");
async function handleGetFile(req, res, deps) {
  const ROUTE2 = routeName(req, "GET /file");
  const factory = getFsFactory(req, res);
  if (!factory) return;
  const clientId = deps.parseClientId(req, res);
  if (clientId === null) return;
  const queryPath = requireStringQuery(res, req.query["path"], "path", ROUTE2);
  if (queryPath === null) return;
  const maxBytes = parseIntInRange(req.query["maxBytes"], 1, 256 * 1024);
  if (maxBytes === null) {
    applyReadHeaders(res);
    res.status(400).json({
      errorKind: "parse_error",
      error: "`maxBytes` must be a positive integer in [1, 262144]",
      status: 400
    });
    return;
  }
  const line = parseIntInRange(req.query["line"], 1, Number.MAX_SAFE_INTEGER);
  if (line === null) {
    applyReadHeaders(res);
    res.status(400).json({
      errorKind: "parse_error",
      error: "`line` must be a positive integer",
      status: 400
    });
    return;
  }
  const limit = parseIntInRange(req.query["limit"], 1, MAX_FILE_LINE_LIMIT);
  if (limit === null) {
    applyReadHeaders(res);
    res.status(400).json({
      errorKind: "parse_error",
      error: `\`limit\` must be a positive integer in [1, ${MAX_FILE_LINE_LIMIT}]`,
      status: 400
    });
    return;
  }
  const fs3 = factory.forRequest({
    originatorClientId: clientId ?? void 0,
    route: ROUTE2
  });
  try {
    const resolved = await fs3.resolve(queryPath, "read");
    const out = await fs3.readText(resolved, { maxBytes, line, limit });
    const returnedBytes = Buffer.byteLength(out.content, "utf-8");
    applyReadHeaders(res);
    res.status(200).json({
      kind: "file",
      path: workspaceRelative(req, resolved),
      content: out.content,
      encoding: out.meta.encoding ?? "utf-8",
      bom: out.meta.bom === true,
      lineEnding: out.meta.lineEnding,
      sizeBytes: out.meta.sizeBytes ?? returnedBytes,
      returnedBytes,
      truncated: out.meta.truncated === true,
      hash: out.meta.hash,
      matchedIgnore: out.meta.matchedIgnore ?? null,
      originalLineCount: out.meta.originalLineCount ?? null
    });
  } catch (err) {
    sendFsError(res, err, ROUTE2);
  }
}
__name(handleGetFile, "handleGetFile");
async function handleGetFileBytes(req, res, deps) {
  const ROUTE2 = routeName(req, "GET /file/bytes");
  const factory = getFsFactory(req, res);
  if (!factory) return;
  const clientId = deps.parseClientId(req, res);
  if (clientId === null) return;
  const queryPath = requireStringQuery(res, req.query["path"], "path", ROUTE2);
  if (queryPath === null) return;
  const offset = parseIntInRange(
    req.query["offset"],
    0,
    Number.MAX_SAFE_INTEGER
  );
  if (offset === null) {
    applyReadHeaders(res);
    res.status(400).json({
      errorKind: "parse_error",
      error: "`offset` must be a non-negative safe integer",
      status: 400
    });
    return;
  }
  const maxBytes = parseIntInRange(req.query["maxBytes"], 1, MAX_READ_BYTES);
  if (maxBytes === null) {
    applyReadHeaders(res);
    res.status(400).json({
      errorKind: "parse_error",
      error: `\`maxBytes\` must be a positive integer in [1, ${MAX_READ_BYTES}]`,
      status: 400
    });
    return;
  }
  const fs3 = factory.forRequest({
    originatorClientId: clientId ?? void 0,
    route: ROUTE2
  });
  try {
    const resolved = await fs3.resolve(queryPath, "read");
    const out = await fs3.readBytesWindow(resolved, {
      offset: offset ?? 0,
      maxBytes: maxBytes ?? DEFAULT_FILE_BYTES_MAX_BYTES
    });
    applyReadHeaders(res);
    res.status(200).json({
      kind: "file_bytes",
      path: workspaceRelative(req, resolved),
      offset: out.offset,
      sizeBytes: out.sizeBytes,
      returnedBytes: out.returnedBytes,
      truncated: out.truncated,
      contentBase64: out.buffer.toString("base64"),
      ...out.hash ? { hash: out.hash } : {}
    });
  } catch (err) {
    sendFsError(res, err, ROUTE2);
  }
}
__name(handleGetFileBytes, "handleGetFileBytes");
async function handleGetStat(req, res, deps) {
  const ROUTE2 = routeName(req, "GET /stat");
  const factory = getFsFactory(req, res);
  if (!factory) return;
  const clientId = deps.parseClientId(req, res);
  if (clientId === null) return;
  const queryPath = requireStringQuery(res, req.query["path"], "path", ROUTE2);
  if (queryPath === null) return;
  const fs3 = factory.forRequest({
    originatorClientId: clientId ?? void 0,
    route: ROUTE2
  });
  try {
    const resolved = await fs3.resolve(queryPath, "stat");
    const st = await fs3.stat(resolved);
    applyReadHeaders(res);
    res.status(200).json({
      kind: "stat",
      path: workspaceRelative(req, resolved),
      type: st.kind,
      sizeBytes: st.sizeBytes,
      modifiedMs: st.modifiedMs
    });
  } catch (err) {
    sendFsError(res, err, ROUTE2);
  }
}
__name(handleGetStat, "handleGetStat");
async function handleGetList(req, res, deps) {
  const ROUTE2 = routeName(req, "GET /list");
  const factory = getFsFactory(req, res);
  if (!factory) return;
  const clientId = deps.parseClientId(req, res);
  if (clientId === null) return;
  const queryPath = requireStringQuery(res, req.query["path"], "path", ROUTE2);
  if (queryPath === null) return;
  const includeIgnored = parseBoolFlag(req.query["includeIgnored"]);
  const fs3 = factory.forRequest({
    originatorClientId: clientId ?? void 0,
    route: ROUTE2
  });
  try {
    const resolved = await fs3.resolve(queryPath, "list");
    const entries = await fs3.list(resolved, {
      includeIgnored,
      maxEntries: MAX_LIST_ENTRIES + 1
    });
    let truncated = false;
    let returned = entries;
    if (returned.length > MAX_LIST_ENTRIES) {
      returned = returned.slice(0, MAX_LIST_ENTRIES);
      truncated = true;
    }
    applyReadHeaders(res);
    res.status(200).json({
      kind: "list",
      path: workspaceRelative(req, resolved),
      entries: returned,
      truncated,
      matchedIgnore: null
    });
  } catch (err) {
    sendFsError(res, err, ROUTE2);
  }
}
__name(handleGetList, "handleGetList");
async function handleGetGlob(req, res, deps) {
  const ROUTE2 = routeName(req, "GET /glob");
  const factory = getFsFactory(req, res);
  if (!factory) return;
  const clientId = deps.parseClientId(req, res);
  if (clientId === null) return;
  const pattern = requireStringQuery(
    res,
    req.query["pattern"],
    "pattern",
    ROUTE2
  );
  if (pattern === null) return;
  const includeIgnored = parseBoolFlag(req.query["includeIgnored"]);
  const maxResults = parseIntInRange(
    req.query["maxResults"],
    1,
    MAX_GLOB_MAX_RESULTS
  );
  if (maxResults === null) {
    applyReadHeaders(res);
    res.status(400).json({
      errorKind: "parse_error",
      error: `\`maxResults\` must be a positive integer in [1, ${MAX_GLOB_MAX_RESULTS}]`,
      status: 400
    });
    return;
  }
  const cwdRaw = req.query["cwd"];
  const cwdString = typeof cwdRaw === "string" && cwdRaw.length > 0 ? cwdRaw : void 0;
  const fs3 = factory.forRequest({
    originatorClientId: clientId ?? void 0,
    route: ROUTE2
  });
  const start = performance.now();
  try {
    const cwdResolved = cwdString ? await fs3.resolve(cwdString, "list") : void 0;
    const cap = maxResults ?? DEFAULT_GLOB_MAX_RESULTS;
    const probe = await fs3.glob(pattern, {
      cwd: cwdResolved,
      includeIgnored,
      maxResults: cap + 1
    });
    const truncated = probe.length > cap;
    const trimmed = truncated ? probe.slice(0, cap) : probe;
    const relMatches = trimmed.map((m) => workspaceRelative(req, m));
    applyReadHeaders(res);
    res.status(200).json({
      kind: "glob",
      pattern,
      cwd: cwdString ?? "",
      matches: relMatches,
      count: relMatches.length,
      truncated,
      durationMs: Math.round(performance.now() - start)
    });
  } catch (err) {
    sendFsError(res, err, ROUTE2);
  }
}
__name(handleGetGlob, "handleGetGlob");
function workspaceRelative(req, resolved) {
  const boundWorkspace = getWorkspaceRouteContext(req)?.runtime.workspaceCwd ?? req.app.locals.boundWorkspace;
  if (!boundWorkspace) {
    throw new Error("bound workspace is not configured");
  }
  let rel = path6.relative(boundWorkspace, resolved);
  if (isOutsideWorkspaceRelative(rel)) {
    try {
      rel = path6.relative(canonicalizeWorkspace(boundWorkspace), resolved);
    } catch {
      throw new FsError(
        "path_outside_workspace",
        "path resolved outside workspace"
      );
    }
  }
  if (isOutsideWorkspaceRelative(rel)) {
    throw new FsError(
      "path_outside_workspace",
      "path resolved outside workspace"
    );
  }
  if (rel === "") return ".";
  return path6.sep === "/" ? rel : rel.split(path6.sep).join("/");
}
__name(workspaceRelative, "workspaceRelative");
function isOutsideWorkspaceRelative(rel) {
  return rel === ".." || rel.startsWith(`..${path6.sep}`) || path6.isAbsolute(rel);
}
__name(isOutsideWorkspaceRelative, "isOutsideWorkspaceRelative");
function registerWorkspaceFileReadRoutes(app, deps) {
  app.get("/file", (req, res) => handleGetFile(req, res, deps));
  app.get("/file/bytes", (req, res) => handleGetFileBytes(req, res, deps));
  app.get("/stat", (req, res) => handleGetStat(req, res, deps));
  app.get("/list", (req, res) => handleGetList(req, res, deps));
  app.get("/glob", (req, res) => handleGetGlob(req, res, deps));
}
__name(registerWorkspaceFileReadRoutes, "registerWorkspaceFileReadRoutes");
function registerWorkspaceQualifiedFileReadRoutes(app, deps) {
  const resolve5 = /* @__PURE__ */ __name((req, res) => {
    const runtime = resolveWorkspaceRuntimeFromParam(
      deps.workspaceRegistry,
      req,
      res
    );
    if (!runtime) return false;
    setWorkspaceRouteContext(req, {
      runtime,
      routePrefix: "GET /workspaces/:workspace"
    });
    return true;
  }, "resolve");
  app.get("/workspaces/:workspace/file", (req, res) => {
    if (!resolve5(req, res)) return;
    void handleGetFile(req, res, deps);
  });
  app.get("/workspaces/:workspace/file/bytes", (req, res) => {
    if (!resolve5(req, res)) return;
    void handleGetFileBytes(req, res, deps);
  });
  app.get("/workspaces/:workspace/stat", (req, res) => {
    if (!resolve5(req, res)) return;
    void handleGetStat(req, res, deps);
  });
  app.get("/workspaces/:workspace/list", (req, res) => {
    if (!resolve5(req, res)) return;
    void handleGetList(req, res, deps);
  });
  app.get("/workspaces/:workspace/glob", (req, res) => {
    if (!resolve5(req, res)) return;
    void handleGetGlob(req, res, deps);
  });
}
__name(registerWorkspaceQualifiedFileReadRoutes, "registerWorkspaceQualifiedFileReadRoutes");

// packages/cli/src/serve/routes/workspace-setup-github.ts
var ROUTE = "POST /workspace/setup-github";
function registerWorkspaceSetupGithubRoutes(app, deps) {
  app.post(
    "/workspace/setup-github",
    deps.mutate({ strict: true }),
    (req, res) => handleSetupGithub(req, res, deps)
  );
}
__name(registerWorkspaceSetupGithubRoutes, "registerWorkspaceSetupGithubRoutes");
async function handleSetupGithub(req, res, deps) {
  const factory = getFsFactory2(req, res);
  if (!factory) return;
  const body = deps.safeBody(req);
  if (body["consent"] !== true) {
    applyReadHeaders(res);
    res.status(400).json({
      error: "`consent` must be true",
      code: "github_setup_consent_required",
      status: 400
    });
    return;
  }
  const clientId = deps.parseClientId(req, res);
  if (clientId === null) return;
  const originatorClientId = validateClientId(clientId, deps, res);
  if (originatorClientId === null) return;
  try {
    const result = await setupGithub({
      cwd: deps.boundWorkspace,
      workspaceRoot: deps.boundWorkspace,
      proxy: resolveSetupGithubProxy(deps.boundWorkspace),
      abortSignal: requestAbortSignal(req, res),
      fileOps: createSetupGithubFileOps(factory, ROUTE, originatorClientId)
    });
    deps.bridge.publishWorkspaceEvent({
      type: "github_setup_completed",
      data: setupGithubEventData(result),
      ...originatorClientId ? { originatorClientId } : {}
    });
    applyReadHeaders(res);
    res.status(200).json(result);
  } catch (error2) {
    sendSetupGithubError(res, error2, deps.boundWorkspace);
  }
}
__name(handleSetupGithub, "handleSetupGithub");
function getFsFactory2(req, res) {
  const factory = req.app.locals.fsFactory;
  if (!factory) {
    applyReadHeaders(res);
    res.status(500).json({
      error: "workspace filesystem factory is not configured",
      code: "internal_error",
      status: 500
    });
    return null;
  }
  return factory;
}
__name(getFsFactory2, "getFsFactory");
function validateClientId(clientId, deps, res) {
  if (clientId === void 0) return void 0;
  if (!deps.bridge.knownClientIds().has(clientId)) {
    applyReadHeaders(res);
    res.status(400).json({
      error: `Client id "${clientId}" is not registered for this workspace`,
      code: "invalid_client_id",
      clientId
    });
    return null;
  }
  return clientId;
}
__name(validateClientId, "validateClientId");
function createSetupGithubFileOps(factory, route, originatorClientId) {
  const fs3 = factory.forRequest({
    route,
    ...originatorClientId ? { originatorClientId } : {}
  });
  return {
    assertCanWrite() {
      try {
        factory.assertCanWrite();
      } catch (error2) {
        throw new SetupGithubError(
          "github_setup_untrusted_workspace",
          error2 instanceof Error ? error2.message : "workspace is not trusted; write operations are forbidden",
          403
        );
      }
    },
    async ensureWorkflowDirectory(gitRepoRoot) {
      await ensureDirectoryWithoutSymlink(gitRepoRoot, [
        ".github",
        "workflows"
      ]);
    },
    async writeTextFile(_gitRepoRoot, relativePath, content) {
      const resolved = await fs3.resolve(relativePath, "write");
      const out = await fs3.writeTextOverwrite(resolved, content);
      return { sizeBytes: out.sizeBytes };
    },
    async readTextFile(_gitRepoRoot, relativePath) {
      try {
        const resolved = await fs3.resolve(relativePath, "read");
        const out = await fs3.readText(resolved);
        return out.content;
      } catch (error2) {
        if (isFsError(error2) && error2.kind === "path_not_found") {
          return void 0;
        }
        throw error2;
      }
    }
  };
}
__name(createSetupGithubFileOps, "createSetupGithubFileOps");
async function ensureDirectoryWithoutSymlink(root, segments) {
  await assertDirectoryWithoutSymlink(root, "Repository root");
  let current = root;
  const checkedSegments = [];
  for (const segment of segments) {
    current = path7.join(current, segment);
    checkedSegments.push(segment);
    const label = `Workspace path "${checkedSegments.join("/")}"`;
    try {
      const stat2 = await fsp3.lstat(current);
      if (stat2.isSymbolicLink()) {
        throw new SetupGithubError(
          "github_setup_invalid_workspace",
          `${label} must not be a symlink.`,
          400
        );
      }
      if (!stat2.isDirectory()) {
        throw new SetupGithubError(
          "github_setup_invalid_workspace",
          `${label} must be a directory.`,
          400
        );
      }
    } catch (error2) {
      if (error2 instanceof SetupGithubError) throw error2;
      if (error2.code !== "ENOENT") throw error2;
      try {
        await fsp3.mkdir(current, { mode: 493 });
      } catch (mkdirError) {
        if (mkdirError.code !== "EEXIST") {
          throw mkdirError;
        }
      }
      const postStat = await fsp3.lstat(current);
      if (postStat.isSymbolicLink()) {
        throw new SetupGithubError(
          "github_setup_invalid_workspace",
          `${label} must not be a symlink.`,
          400
        );
      }
      if (!postStat.isDirectory()) {
        throw new SetupGithubError(
          "github_setup_invalid_workspace",
          `${label} must be a directory.`,
          400
        );
      }
    }
  }
}
__name(ensureDirectoryWithoutSymlink, "ensureDirectoryWithoutSymlink");
async function assertDirectoryWithoutSymlink(target, label) {
  const stat2 = await fsp3.lstat(target);
  if (stat2.isSymbolicLink()) {
    throw new SetupGithubError(
      "github_setup_invalid_workspace",
      `${label} must not be a symlink.`,
      400
    );
  }
  if (!stat2.isDirectory()) {
    throw new SetupGithubError(
      "github_setup_invalid_workspace",
      `${label} must be a directory.`,
      400
    );
  }
}
__name(assertDirectoryWithoutSymlink, "assertDirectoryWithoutSymlink");
function sanitizeSetupGithubMessage(message, boundWorkspace) {
  return message.split(boundWorkspace).join("<workspace>");
}
__name(sanitizeSetupGithubMessage, "sanitizeSetupGithubMessage");
function sanitizeSetupGithubResult(result, boundWorkspace) {
  return {
    ...result,
    workflows: result.workflows.map((workflow) => ({
      ...workflow,
      ...workflow.error ? {
        error: sanitizeSetupGithubMessage(workflow.error, boundWorkspace)
      } : {}
    })),
    gitignore: {
      ...result.gitignore,
      ...result.gitignore.error ? {
        error: sanitizeSetupGithubMessage(
          result.gitignore.error,
          boundWorkspace
        )
      } : {}
    }
  };
}
__name(sanitizeSetupGithubResult, "sanitizeSetupGithubResult");
function sendSetupGithubError(res, error2, boundWorkspace) {
  applyReadHeaders(res);
  if (error2 instanceof SetupGithubError) {
    res.status(error2.status).json({
      error: sanitizeSetupGithubMessage(error2.message, boundWorkspace),
      code: error2.code,
      status: error2.status,
      ...error2.partial ? {
        partial: true,
        result: error2.partialResult ? sanitizeSetupGithubResult(error2.partialResult, boundWorkspace) : null
      } : {}
    });
    return;
  }
  writeStderrLine(
    `[setup-github] unexpected error: ${error2 instanceof Error ? error2.message : String(error2)}`
  );
  res.status(500).json({
    error: "An internal error occurred during GitHub setup.",
    code: "github_setup_failed",
    status: 500
  });
}
__name(sendSetupGithubError, "sendSetupGithubError");
function setupGithubEventData(result) {
  return {
    releaseTag: result.releaseTag,
    readmeUrl: result.readmeUrl,
    ...result.secretsUrl ? { secretsUrl: result.secretsUrl } : {},
    workflows: result.workflows,
    gitignore: result.gitignore,
    warnings: result.warnings
  };
}
__name(setupGithubEventData, "setupGithubEventData");
function resolveSetupGithubProxy(boundWorkspace) {
  const settings = loadSettings(boundWorkspace, { skipLoadEnvironment: true });
  const trustState = getWorkspaceTrustStatus(
    settingsForSetupGithubTrust(settings),
    boundWorkspace
  ).effective.state;
  const settingsProxy = trustState === "trusted" ? settings.merged.proxy : settings.user.settings.proxy || settings.system.settings.proxy || settings.systemDefaults.settings.proxy;
  return settingsProxy || process.env["HTTPS_PROXY"] || process.env["https_proxy"] || process.env["HTTP_PROXY"] || process.env["http_proxy"];
}
__name(resolveSetupGithubProxy, "resolveSetupGithubProxy");
function settingsForSetupGithubTrust(settings) {
  const userFolderTrust = settings.user.settings.security?.folderTrust;
  const systemFolderTrust = settings.system.settings.security?.folderTrust;
  if (!userFolderTrust && !systemFolderTrust) return {};
  return {
    security: {
      folderTrust: {
        ...systemFolderTrust,
        ...userFolderTrust
      }
    }
  };
}
__name(settingsForSetupGithubTrust, "settingsForSetupGithubTrust");
function requestAbortSignal(req, res) {
  const controller = new AbortController();
  const abort = /* @__PURE__ */ __name(() => controller.abort(), "abort");
  req.once("aborted", abort);
  res.once("close", () => {
    if (!res.writableEnded) abort();
  });
  return controller.signal;
}
__name(requestAbortSignal, "requestAbortSignal");

// packages/cli/src/serve/routes/workspace-voice.ts
init_esbuild_shims();
var import_express = __toESM(require_express(), 1);

// packages/cli/src/serve/validation-limits.ts
init_esbuild_shims();
var MAX_TRUST_REASON_LENGTH = 1024;
var MAX_VOICE_LANGUAGE_LENGTH = 1024;
var MAX_VOICE_MODEL_LENGTH = 256;

// packages/cli/src/serve/routes/workspace-voice.ts
function sendVoiceError(res, err) {
  if (err instanceof WorkspaceVoiceError) {
    res.status(err.status).json({ error: err.message, code: err.code });
    return true;
  }
  return false;
}
__name(sendVoiceError, "sendVoiceError");
function broadcastVoiceWrite(deps, write, clientId) {
  try {
    deps.broadcastSettingsChanged(
      write.key,
      write.value,
      voiceSettingsScopeToWire(write.scope),
      clientId
    );
  } catch (err) {
    writeStderrLine(
      `qwen serve: POST /workspace/voice broadcast error (key=${write.key}, scope=${voiceSettingsScopeToWire(write.scope)}): ${err instanceof Error ? err.message : String(err)}`
    );
  }
}
__name(broadcastVoiceWrite, "broadcastVoiceWrite");
function parseWorkspaceVoiceUpdateParams(body) {
  const parsed = {};
  if ("enabled" in body) {
    if (typeof body["enabled"] !== "boolean") {
      return { error: "`enabled` must be a boolean", code: "invalid_enabled" };
    }
    parsed.enabled = body["enabled"];
  }
  if ("mode" in body) {
    if (!isVoiceMode(body["mode"])) {
      return {
        error: '`mode` must be either "hold" or "tap"',
        code: "invalid_voice_mode"
      };
    }
    parsed.mode = body["mode"];
  }
  if ("language" in body) {
    if (typeof body["language"] !== "string") {
      return {
        error: "`language` must be a string",
        code: "invalid_voice_language"
      };
    }
    const language = body["language"].trim();
    if (language.length > MAX_VOICE_LANGUAGE_LENGTH) {
      return {
        error: `\`language\` exceeds the ${MAX_VOICE_LANGUAGE_LENGTH}-character limit`,
        code: "invalid_voice_language"
      };
    }
    parsed.language = language;
  }
  if ("voiceModel" in body) {
    if (typeof body["voiceModel"] !== "string") {
      return {
        error: "`voiceModel` must be a non-empty string",
        code: "invalid_voice_model"
      };
    }
    const voiceModel = body["voiceModel"].trim();
    if (!voiceModel) {
      return {
        error: "`voiceModel` must be a non-empty string",
        code: "invalid_voice_model"
      };
    }
    if (voiceModel.length > MAX_VOICE_MODEL_LENGTH) {
      return {
        error: `\`voiceModel\` exceeds the ${MAX_VOICE_MODEL_LENGTH}-character limit`,
        code: "invalid_voice_model"
      };
    }
    parsed.voiceModel = voiceModel;
  }
  if (Object.keys(parsed).length === 0) {
    return {
      error: EMPTY_WORKSPACE_VOICE_UPDATE_ERROR,
      code: "invalid_voice_update"
    };
  }
  return parsed;
}
__name(parseWorkspaceVoiceUpdateParams, "parseWorkspaceVoiceUpdateParams");
async function persistVoiceUpdate(deps, settings, update, clientId, workspaceTrusted) {
  if (!deps.persistSettings && !deps.persistSetting) {
    throw new Error("workspace voice settings persistence is not available");
  }
  const writes = buildWorkspaceVoiceSettingsWrites(settings, update, {
    workspaceTrusted,
    ...deps.scopeOverride ? { scopeOverride: deps.scopeOverride } : {}
  });
  if (deps.persistSettings) {
    try {
      await deps.persistSettings(deps.boundWorkspace, writes);
    } catch (err) {
      if (err instanceof WorkspaceSettingsPartialPersistError) {
        for (const write of err.committedWrites) {
          broadcastVoiceWrite(deps, write, clientId);
        }
      }
      throw err;
    }
    for (const write of writes) {
      broadcastVoiceWrite(deps, write, clientId);
    }
  } else {
    const committed = [];
    for (const write of writes) {
      try {
        await deps.persistSetting(
          deps.boundWorkspace,
          write.scope,
          write.key,
          write.value
        );
      } catch (err) {
        writeStderrLine(
          `qwen serve: POST /workspace/voice partial persist error (workspace=${deps.boundWorkspace}, committed=${committed.length}/${writes.length}, failedKey=${write.key}, failedScope=${voiceSettingsScopeToWire(write.scope)}): ${err instanceof Error ? err.message : String(err)}`
        );
        for (const committedWrite of committed) {
          broadcastVoiceWrite(deps, committedWrite, clientId);
        }
        throw new WorkspaceSettingsPartialPersistError(
          `Voice settings partial persist failed: committed=${committed.length}/${writes.length}`,
          committed,
          err
        );
      }
      committed.push(write);
    }
    for (const write of committed) {
      broadcastVoiceWrite(deps, write, clientId);
    }
  }
}
__name(persistVoiceUpdate, "persistVoiceUpdate");
function normalizeContentType(req) {
  return req.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase();
}
__name(normalizeContentType, "normalizeContentType");
function requestAbortSignal2(req, res) {
  const controller = new AbortController();
  const abort = /* @__PURE__ */ __name(() => controller.abort(), "abort");
  req.once("aborted", abort);
  res.once("close", () => {
    if (!res.writableEnded) abort();
  });
  return controller.signal;
}
__name(requestAbortSignal2, "requestAbortSignal");
function loadVoiceSettings(deps) {
  return loadSettings(
    deps.boundWorkspace,
    deps.env ? { skipLoadEnvironment: true } : true
  );
}
__name(loadVoiceSettings, "loadVoiceSettings");
function admissionState(req) {
  return req.voiceAdmissionState;
}
__name(admissionState, "admissionState");
function admissionLease(req) {
  return admissionState(req)?.lease;
}
__name(admissionLease, "admissionLease");
function installAdmissionLease(req, res, deps) {
  const result = deps.acquireVoiceLease?.();
  if (!result) return true;
  if (result.kind === "rejected") {
    if (result.reason === "draining") {
      sendWorkspaceDraining(res);
    } else {
      res.set("Retry-After", "5").status(503).json({
        error: "Too many voice sessions in progress; try again shortly.",
        code: "voice_capacity_exceeded"
      });
    }
    return false;
  }
  let released = false;
  const release = /* @__PURE__ */ __name(() => {
    if (released) return;
    released = true;
    result.lease.release();
  }, "release");
  const state = {
    lease: result.lease,
    operationStarted: false,
    release
  };
  req.voiceAdmissionState = state;
  const releaseBeforeOperation = /* @__PURE__ */ __name(() => {
    if (!state.operationStarted) release();
  }, "releaseBeforeOperation");
  res.once("finish", releaseBeforeOperation);
  res.once("close", releaseBeforeOperation);
  return true;
}
__name(installAdmissionLease, "installAdmissionLease");
function beginVoiceOperation(req) {
  const state = admissionState(req);
  if (!state) return;
  state.operationStarted = true;
  return state.release;
}
__name(beginVoiceOperation, "beginVoiceOperation");
function combinedAbortSignal(req, res) {
  const requestSignal = requestAbortSignal2(req, res);
  const leaseSignal = admissionLease(req)?.signal;
  return leaseSignal ? AbortSignal.any([requestSignal, leaseSignal]) : requestSignal;
}
__name(combinedAbortSignal, "combinedAbortSignal");
function sendWorkspaceDraining(res) {
  res.set("Retry-After", "5").status(503).json({
    error: "Workspace runtime is being removed",
    code: "workspace_draining"
  });
}
__name(sendWorkspaceDraining, "sendWorkspaceDraining");
function isSupportedAudioContentType(contentType) {
  return typeof contentType === "string" && (contentType.startsWith("audio/") || contentType === "application/octet-stream");
}
__name(isSupportedAudioContentType, "isSupportedAudioContentType");
function readBinaryBody(req) {
  const body = req.body;
  if (body instanceof Uint8Array || Buffer.isBuffer(body)) {
    return body;
  }
  if (ArrayBuffer.isView(body)) {
    return new Uint8Array(body.buffer, body.byteOffset, body.byteLength);
  }
  return void 0;
}
__name(readBinaryBody, "readBinaryBody");
function sendUnsupportedVoiceContentType(res) {
  res.status(415).json({
    error: "Content-Type must be audio/* or application/octet-stream for voice transcription",
    code: "unsupported_voice_content_type"
  });
}
__name(sendUnsupportedVoiceContentType, "sendUnsupportedVoiceContentType");
function handleVoiceStatus(res, deps, route) {
  try {
    res.status(200).json(
      buildWorkspaceVoiceStatus(deps.boundWorkspace, loadVoiceSettings(deps))
    );
  } catch (err) {
    writeStderrLine(
      `qwen serve: ${route} error: ${err instanceof Error ? err.message : String(err)}`
    );
    res.status(500).json({
      error: "Failed to load voice settings",
      code: "internal_error"
    });
  }
}
__name(handleVoiceStatus, "handleVoiceStatus");
async function handleVoiceUpdate(req, res, deps, route) {
  if (!deps.persistSettings && !deps.persistSetting) {
    res.status(501).json({
      error: "Workspace voice settings persistence is not available",
      code: "not_implemented"
    });
    return;
  }
  const parsed = parseWorkspaceVoiceUpdateParams(deps.safeBody(req));
  if ("error" in parsed) {
    res.status(400).json(parsed);
    return;
  }
  const settings = loadVoiceSettings(deps);
  try {
    validateWorkspaceVoiceState(settings, parsed, { env: deps.env });
  } catch (err) {
    if (sendVoiceError(res, err)) return;
    throw err;
  }
  const clientId = deps.parseAndValidateClientId(req, res);
  if (clientId === null) return;
  try {
    const workspaceTrusted = getWorkspaceTrustStatus(settings.merged, deps.boundWorkspace).effective.state === "trusted";
    await persistVoiceUpdate(
      deps,
      settings,
      parsed,
      clientId,
      workspaceTrusted
    );
  } catch (err) {
    writeStderrLine(
      `qwen serve: ${route} persist error (workspace=${deps.boundWorkspace}): ${err instanceof Error ? err.message : String(err)}`
    );
    res.status(500).json({
      error: "Failed to persist voice settings",
      code: "persist_error"
    });
    return;
  }
  try {
    res.status(200).json(
      buildWorkspaceVoiceStatus(deps.boundWorkspace, loadVoiceSettings(deps))
    );
  } catch (err) {
    writeStderrLine(
      `qwen serve: ${route} reload error after persist (workspace=${deps.boundWorkspace}): ${err instanceof Error ? err.message : String(err)}`
    );
    res.status(500).json({
      error: "Voice settings persisted but failed to reload",
      code: "internal_error"
    });
  }
}
__name(handleVoiceUpdate, "handleVoiceUpdate");
async function handleVoiceTranscription(req, res, deps, route) {
  const contentType = normalizeContentType(req);
  if (!isSupportedAudioContentType(contentType)) {
    sendUnsupportedVoiceContentType(res);
    return;
  }
  if (admissionLease(req)?.signal.aborted) {
    sendWorkspaceDraining(res);
    return;
  }
  const clientId = deps.parseAndValidateClientId(req, res);
  if (clientId === null) return;
  const data = readBinaryBody(req);
  if (!data || data.byteLength === 0) {
    res.status(400).json({
      error: "Voice audio body must be non-empty binary data",
      code: "invalid_voice_audio"
    });
    return;
  }
  const settings = loadVoiceSettings(deps);
  if (!isVoiceEnabled(settings)) {
    res.status(403).json({
      error: "Voice transcription is disabled for this workspace",
      code: "voice_disabled"
    });
    return;
  }
  const queryVoiceModel = req.query["voiceModel"];
  if (queryVoiceModel !== void 0 && typeof queryVoiceModel !== "string") {
    res.status(400).json({
      error: "`voiceModel` query parameter must be a string",
      code: "invalid_voice_model"
    });
    return;
  }
  const requestedVoiceModel = typeof queryVoiceModel === "string" ? queryVoiceModel.trim() : "";
  if (requestedVoiceModel && requestedVoiceModel.length > MAX_VOICE_MODEL_LENGTH) {
    res.status(400).json({
      error: `\`voiceModel\` exceeds the ${MAX_VOICE_MODEL_LENGTH}-character limit`,
      code: "invalid_voice_model"
    });
    return;
  }
  const voiceModel = requestedVoiceModel || readVoiceModel(settings);
  if (!voiceModel) {
    res.status(400).json({
      error: "A valid voiceModel is required before transcription.",
      code: "voice_model_required"
    });
    return;
  }
  try {
    const releaseOperation = beginVoiceOperation(req);
    let result;
    try {
      result = await (deps.transcribe ?? transcribeWorkspaceVoiceAudio)({
        data,
        mimeType: contentType,
        voiceModel,
        settings,
        workspaceCwd: deps.boundWorkspace,
        env: deps.env,
        abortSignal: combinedAbortSignal(req, res)
      });
    } finally {
      releaseOperation?.();
    }
    if (admissionLease(req)?.signal.aborted) {
      sendWorkspaceDraining(res);
      return;
    }
    res.status(200).json({ v: 1, ...result });
  } catch (err) {
    if (admissionLease(req)?.signal.aborted) {
      sendWorkspaceDraining(res);
      return;
    }
    if (sendVoiceError(res, err)) return;
    const message = sanitizeVoiceErrorMessage(
      err instanceof Error ? err.message : String(err)
    );
    writeStderrLine(
      `qwen serve: ${route} error (workspace=${deps.boundWorkspace}): ${message}`
    );
    res.status(502).json({
      error: "Voice transcription failed",
      code: "voice_transcription_failed"
    });
  }
}
__name(handleVoiceTranscription, "handleVoiceTranscription");
function admitVoiceTranscription(req, res, deps) {
  if (!isSupportedAudioContentType(normalizeContentType(req))) {
    sendUnsupportedVoiceContentType(res);
    return false;
  }
  return installAdmissionLease(req, res, deps);
}
__name(admitVoiceTranscription, "admitVoiceTranscription");
function voiceAudioBodyParser() {
  const parse = import_express.default.raw({
    type: /* @__PURE__ */ __name((req) => isSupportedAudioContentType(
      req.headers["content-type"]?.split(";", 1)[0]?.trim().toLowerCase()
    ), "type"),
    limit: "10mb"
  });
  return (req, res, next) => {
    const signal = admissionLease(req)?.signal;
    let aborted = signal?.aborted === true;
    const onAbort = /* @__PURE__ */ __name(() => {
      aborted = true;
      if (!res.headersSent) sendWorkspaceDraining(res);
      const destroyRequest = /* @__PURE__ */ __name(() => {
        if (!req.destroyed) req.destroy();
      }, "destroyRequest");
      if (res.writableFinished) destroyRequest();
      else {
        res.once("finish", destroyRequest);
        res.once("close", destroyRequest);
      }
    }, "onAbort");
    if (aborted) {
      onAbort();
      return;
    }
    signal?.addEventListener("abort", onAbort, { once: true });
    parse(req, res, (err) => {
      signal?.removeEventListener("abort", onAbort);
      if (aborted || signal?.aborted) {
        if (!res.headersSent) sendWorkspaceDraining(res);
        return;
      }
      next(err);
    });
  };
}
__name(voiceAudioBodyParser, "voiceAudioBodyParser");
function registerWorkspaceVoiceRoutes(app, deps) {
  app.get(
    "/workspace/voice",
    (_req, res) => handleVoiceStatus(res, deps, "GET /workspace/voice")
  );
  app.post(
    "/workspace/voice",
    deps.mutate({ strict: true }),
    async (req, res) => {
      await handleVoiceUpdate(req, res, deps, "POST /workspace/voice");
    }
  );
  app.post(
    "/workspace/voice/transcribe",
    deps.mutate({ strict: true }),
    (req, res, next) => {
      if (admitVoiceTranscription(req, res, deps)) next();
    },
    voiceAudioBodyParser(),
    async (req, res) => {
      await handleVoiceTranscription(
        req,
        res,
        deps,
        "POST /workspace/voice/transcribe"
      );
    }
  );
}
__name(registerWorkspaceVoiceRoutes, "registerWorkspaceVoiceRoutes");
function createRuntimeVoiceDeps(runtime, deps) {
  const env = runtime.env.mode === "runtime-overlay" ? runtime.env.effectiveEnv ?? {} : runtime.env.effectiveEnv;
  return {
    boundWorkspace: runtime.workspaceCwd,
    mutate: deps.mutate,
    safeBody: deps.safeBody,
    persistSetting: deps.persistSetting,
    persistSettings: deps.persistSettings,
    transcribe: deps.transcribe,
    ...env ? { env } : {},
    scopeOverride: "Workspace" /* Workspace */,
    acquireVoiceLease: /* @__PURE__ */ __name(() => deps.acquireVoiceLease(runtime), "acquireVoiceLease"),
    broadcastSettingsChanged: /* @__PURE__ */ __name((key, value, scope, clientId) => {
      if (runtime.primary) deps.invalidateServeFeaturesCache();
      runtime.bridge.publishWorkspaceEvent({
        type: "settings_changed",
        data: { key, value, scope },
        originatorClientId: clientId
      });
    }, "broadcastSettingsChanged"),
    parseAndValidateClientId: /* @__PURE__ */ __name((req, res) => deps.parseAndValidateClientId(req, res, runtime), "parseAndValidateClientId")
  };
}
__name(createRuntimeVoiceDeps, "createRuntimeVoiceDeps");
function resolveQualifiedVoiceTarget(req, res, deps, includeDraining = false) {
  const runtime = includeDraining ? resolveManagedWorkspaceRuntimeFromParam(deps.workspaceRegistry, req, res) : resolveWorkspaceRuntimeFromParam(deps.workspaceRegistry, req, res);
  if (!runtime || !requireTrustedWorkspaceRuntime(runtime, res)) return;
  return createRuntimeVoiceDeps(runtime, deps);
}
__name(resolveQualifiedVoiceTarget, "resolveQualifiedVoiceTarget");
function registerWorkspaceQualifiedVoiceRoutes(app, deps) {
  app.get("/workspaces/:workspace/voice", (req, res) => {
    const target = resolveQualifiedVoiceTarget(req, res, deps);
    if (!target) return;
    handleVoiceStatus(res, target, "GET /workspaces/:workspace/voice");
  });
  app.post(
    "/workspaces/:workspace/voice",
    deps.mutate({ strict: true }),
    async (req, res) => {
      const target = resolveQualifiedVoiceTarget(req, res, deps);
      if (!target) return;
      await handleVoiceUpdate(
        req,
        res,
        target,
        "POST /workspaces/:workspace/voice"
      );
    }
  );
  app.post(
    "/workspaces/:workspace/voice/transcribe",
    deps.mutate({ strict: true }),
    (req, res, next) => {
      const target = resolveQualifiedVoiceTarget(req, res, deps, true);
      if (!target) return;
      req.voiceRouteDeps = target;
      if (admitVoiceTranscription(req, res, target)) next();
    },
    voiceAudioBodyParser(),
    async (req, res) => {
      const target = req.voiceRouteDeps;
      if (!target) return;
      await handleVoiceTranscription(
        req,
        res,
        target,
        "POST /workspaces/:workspace/voice/transcribe"
      );
    }
  );
}
__name(registerWorkspaceQualifiedVoiceRoutes, "registerWorkspaceQualifiedVoiceRoutes");

// packages/cli/src/serve/workspace-remember.ts
init_esbuild_shims();
import { randomUUID } from "node:crypto";
var debugLogger = createDebugLogger("WORKSPACE_REMEMBER");
function nowIso() {
  return (/* @__PURE__ */ new Date()).toISOString();
}
__name(nowIso, "nowIso");
function createMemoryTaskId(kind) {
  return `${kind}-${randomUUID()}`;
}
__name(createMemoryTaskId, "createMemoryTaskId");
function touchedScopesFromTopics(topics) {
  const scopes = /* @__PURE__ */ new Set();
  for (const topic of topics) {
    scopes.add(topic === "user" || topic === "feedback" ? "user" : "project");
  }
  return [...scopes];
}
__name(touchedScopesFromTopics, "touchedScopesFromTopics");
function cloneTask(task) {
  const base = {
    taskId: task.taskId,
    status: task.status,
    createdAt: task.createdAt,
    updatedAt: task.updatedAt,
    error: task.error ? { ...task.error } : void 0
  };
  if (task.kind === "remember") {
    return {
      ...base,
      contextMode: task.contextMode,
      result: task.result ? {
        ...task.result,
        filesTouched: [...task.result.filesTouched],
        touchedScopes: [...task.result.touchedScopes]
      } : void 0
    };
  }
  if (task.kind === "forget") {
    return {
      ...base,
      result: task.result ? {
        ...task.result,
        removedEntries: task.result.removedEntries.map((entry) => ({
          ...entry
        })),
        touchedTopics: [...task.result.touchedTopics],
        touchedScopes: [...task.result.touchedScopes]
      } : void 0
    };
  }
  return {
    ...base,
    result: task.result ? {
      ...task.result,
      touchedTopics: [...task.result.touchedTopics]
    } : void 0
  };
}
__name(cloneTask, "cloneTask");
function publicErrorMessage(code, kind) {
  if (code === "managed_memory_unavailable") {
    return "Managed memory is unavailable for this daemon workspace.";
  }
  if (code === "remember_path_escape") {
    return "Remember agent touched a path outside managed memory.";
  }
  if (code === "remember_queue_full") {
    return kind === "remember" ? "Workspace memory remember queue is full." : "Workspace memory task queue is full.";
  }
  if (code === "workspace_draining") {
    return "Workspace runtime is being removed.";
  }
  if (code === "remember_timeout" || code === "forget_timeout" || code === "dream_timeout") {
    return `Workspace memory ${kind} timed out.`;
  }
  return `Workspace memory ${kind} failed.`;
}
__name(publicErrorMessage, "publicErrorMessage");
function publicErrorStatus(code) {
  if (code === "workspace_draining") return 503;
  if (code === "remember_queue_full") return 429;
  if (code === "managed_memory_unavailable") return 409;
  return 500;
}
__name(publicErrorStatus, "publicErrorStatus");
function createTaskError(code, kind, details) {
  const error2 = {
    code,
    message: publicErrorMessage(code, kind)
  };
  if (shouldSuppressRememberErrorDetails(code)) return error2;
  return {
    ...error2,
    ...details ? { details } : {}
  };
}
__name(createTaskError, "createTaskError");
var logWorkspaceMemoryExtractionError = createWorkspaceMemoryExtractionErrorLogger(debugLogger);
var WorkspaceRememberTaskLane = class _WorkspaceRememberTaskLane {
  constructor(bridge, workspaceCwd = "workspace") {
    this.bridge = bridge;
    this.workspaceCwd = workspaceCwd;
  }
  static {
    __name(this, "WorkspaceRememberTaskLane");
  }
  static MAX_TASKS = 1e3;
  static TERMINAL_TASK_TTL_MS = 5 * 6e4;
  // Two-tier pending capacity: all tasks share the global cap, while
  // forget/dream share a smaller sub-cap so bursts cannot starve remember.
  static MAX_PENDING = 16;
  static MAX_NON_REMEMBER_PENDING = 8;
  static NON_REMEMBER_KINDS = /* @__PURE__ */ new Set(
    ["forget", "dream"]
  );
  tasks = /* @__PURE__ */ new Map();
  tail = Promise.resolve();
  draining = false;
  disposed = false;
  beginDrain() {
    this.draining = true;
  }
  cancelDrain() {
    if (!this.disposed) this.draining = false;
  }
  pendingCount() {
    return this.pendingCounts().total;
  }
  dispose() {
    if (this.disposed) return;
    this.disposed = true;
    this.draining = true;
    for (const task of this.tasks.values()) {
      if (task.status !== "queued") continue;
      task.status = "failed";
      task.updatedAt = nowIso();
      task.error = createTaskError(
        "workspace_removed",
        task.kind,
        "Workspace runtime was removed before the task started."
      );
    }
  }
  failRunningTaskAfterRemoval(task) {
    if (!this.disposed || task.status === "completed") return;
    task.status = "failed";
    delete task.result;
    task.updatedAt = nowIso();
    task.error = createTaskError(
      "workspace_removed",
      task.kind,
      "Workspace runtime was removed while the task was running."
    );
  }
  pendingCounts() {
    let total = 0;
    let nonRemember = 0;
    for (const task of this.tasks.values()) {
      if (task.status !== "queued" && task.status !== "running") continue;
      total++;
      if (_WorkspaceRememberTaskLane.NON_REMEMBER_KINDS.has(task.kind)) {
        nonRemember++;
      }
    }
    return { total, nonRemember };
  }
  evictTerminalTasks(nowMs = Date.now()) {
    const cutoffMs = nowMs - _WorkspaceRememberTaskLane.TERMINAL_TASK_TTL_MS;
    for (const [id, task] of this.tasks) {
      if (task.status !== "completed" && task.status !== "failed") continue;
      const updatedAtMs = Date.parse(task.updatedAt);
      if (!Number.isNaN(updatedAtMs) && updatedAtMs <= cutoffMs) {
        this.tasks.delete(id);
      } else if (Number.isNaN(updatedAtMs)) {
        debugLogger.warn(
          "Task with unparseable updatedAt skipped for TTL eviction:",
          {
            taskId: id,
            updatedAt: task.updatedAt
          }
        );
      }
    }
    if (this.tasks.size <= _WorkspaceRememberTaskLane.MAX_TASKS) return;
    for (const [id, task] of this.tasks) {
      if (task.status === "completed" || task.status === "failed") {
        this.tasks.delete(id);
        if (this.tasks.size <= _WorkspaceRememberTaskLane.MAX_TASKS) break;
      }
    }
  }
  assertCapacity(kind) {
    if (this.draining || this.disposed) {
      throw new WorkspaceDrainingError(this.workspaceCwd);
    }
    const pending = this.pendingCounts();
    if (pending.total >= _WorkspaceRememberTaskLane.MAX_PENDING) {
      throw Object.assign(new Error("Workspace memory task queue is full"), {
        code: "remember_queue_full"
      });
    }
    if (_WorkspaceRememberTaskLane.NON_REMEMBER_KINDS.has(kind) && pending.nonRemember >= _WorkspaceRememberTaskLane.MAX_NON_REMEMBER_PENDING) {
      throw Object.assign(new Error("Workspace memory task queue is full"), {
        code: "remember_queue_full"
      });
    }
  }
  queue(task, run) {
    this.tasks.set(task.taskId, task);
    this.evictTerminalTasks();
    const runIfQueued = /* @__PURE__ */ __name(async () => {
      if (task.status !== "queued") return;
      await run();
    }, "runIfQueued");
    this.tail = this.tail.then(runIfQueued, runIfQueued);
    void this.tail.catch((err) => {
      debugLogger.error("Unhandled task lane error:", err);
    });
    return cloneTask(task);
  }
  publishManagedMemoryChanged(params) {
    if (params.touchedScopes.length === 0) return;
    try {
      this.bridge.publishWorkspaceEvent({
        type: "memory_changed",
        data: {
          scope: "managed",
          source: params.source,
          taskId: params.taskId,
          touchedScopes: params.touchedScopes
        },
        ...params.originatorClientId ? { originatorClientId: params.originatorClientId } : {}
      });
    } catch (err) {
      debugLogger.error("Failed to publish memory_changed event:", err);
    }
  }
  enqueue(params) {
    this.assertCapacity("remember");
    const task = {
      kind: "remember",
      taskId: createMemoryTaskId("remember"),
      status: "queued",
      contextMode: params.contextMode,
      createdAt: nowIso(),
      updatedAt: nowIso(),
      ...params.originatorClientId ? { originatorClientId: params.originatorClientId } : {}
    };
    const run = /* @__PURE__ */ __name(async () => {
      task.status = "running";
      task.updatedAt = nowIso();
      try {
        const result = await this.bridge.runWorkspaceMemoryRemember({
          content: params.content,
          contextMode: params.contextMode
        });
        if (!this.disposed) {
          task.status = "completed";
          task.result = {
            summary: result.filesTouched.length > 0 ? "Memory update completed." : "No memory files updated.",
            filesTouched: result.filesTouched,
            touchedScopes: result.touchedScopes
          };
          task.updatedAt = nowIso();
        }
      } catch (err) {
        const code = workspaceMemoryFailureCode(
          err,
          "remember_failed",
          logWorkspaceMemoryExtractionError
        );
        const diagnostics = workspaceMemoryFailureDiagnostics(
          err,
          logWorkspaceMemoryExtractionError
        );
        debugLogger.error("Workspace memory remember task failed:", {
          taskId: task.taskId,
          code,
          details: diagnostics.debugDetails,
          ...diagnostics.stack ? { stack: diagnostics.stack } : {}
        });
        task.status = "failed";
        task.error = createTaskError(code, task.kind, diagnostics.details);
        task.updatedAt = nowIso();
      }
      this.failRunningTaskAfterRemoval(task);
      try {
        if (task.status === "completed" && task.result) {
          this.publishManagedMemoryChanged({
            source: "workspace_memory_remember",
            taskId: task.taskId,
            touchedScopes: task.result.touchedScopes,
            ...params.originatorClientId ? { originatorClientId: params.originatorClientId } : {}
          });
        }
      } finally {
        this.evictTerminalTasks();
      }
    }, "run");
    return this.queue(task, run);
  }
  enqueueForget(params) {
    this.assertCapacity("forget");
    const task = {
      kind: "forget",
      taskId: createMemoryTaskId("forget"),
      status: "queued",
      createdAt: nowIso(),
      updatedAt: nowIso(),
      ...params.originatorClientId ? { originatorClientId: params.originatorClientId } : {}
    };
    const run = /* @__PURE__ */ __name(async () => {
      task.status = "running";
      task.updatedAt = nowIso();
      try {
        const result = await this.bridge.runWorkspaceMemoryForget({
          query: params.query
        });
        if (!this.disposed) {
          task.status = "completed";
          task.result = {
            summary: result.summary ?? formatWorkspaceMemoryForgetSummary(result.removedEntries.length),
            removedEntries: result.removedEntries,
            touchedTopics: result.touchedTopics,
            touchedScopes: result.touchedScopes
          };
          task.updatedAt = nowIso();
        }
      } catch (err) {
        const code = workspaceMemoryFailureCode(
          err,
          "forget_failed",
          logWorkspaceMemoryExtractionError
        );
        const diagnostics = workspaceMemoryFailureDiagnostics(
          err,
          logWorkspaceMemoryExtractionError
        );
        debugLogger.error("Workspace memory forget task failed:", {
          taskId: task.taskId,
          code,
          details: diagnostics.debugDetails,
          ...diagnostics.stack ? { stack: diagnostics.stack } : {}
        });
        task.status = "failed";
        task.error = createTaskError(code, task.kind, diagnostics.details);
        task.updatedAt = nowIso();
      }
      this.failRunningTaskAfterRemoval(task);
      try {
        if (task.status === "completed" && task.result) {
          this.publishManagedMemoryChanged({
            source: "workspace_memory_forget",
            taskId: task.taskId,
            touchedScopes: task.result.touchedScopes,
            ...params.originatorClientId ? { originatorClientId: params.originatorClientId } : {}
          });
        }
      } finally {
        this.evictTerminalTasks();
      }
    }, "run");
    return this.queue(task, run);
  }
  enqueueDream(params) {
    this.assertCapacity("dream");
    const task = {
      kind: "dream",
      taskId: createMemoryTaskId("dream"),
      status: "queued",
      createdAt: nowIso(),
      updatedAt: nowIso(),
      ...params.originatorClientId ? { originatorClientId: params.originatorClientId } : {}
    };
    const run = /* @__PURE__ */ __name(async () => {
      task.status = "running";
      task.updatedAt = nowIso();
      try {
        const result = await this.bridge.runWorkspaceMemoryDream();
        if (!this.disposed) {
          task.status = "completed";
          task.result = {
            summary: result.summary ?? formatWorkspaceMemoryDreamSummary(result.touchedTopics.length),
            touchedTopics: result.touchedTopics,
            dedupedEntries: result.dedupedEntries
          };
          task.updatedAt = nowIso();
        }
      } catch (err) {
        const code = workspaceMemoryFailureCode(
          err,
          "dream_failed",
          logWorkspaceMemoryExtractionError
        );
        const diagnostics = workspaceMemoryFailureDiagnostics(
          err,
          logWorkspaceMemoryExtractionError
        );
        debugLogger.error("Workspace memory dream task failed:", {
          taskId: task.taskId,
          code,
          details: diagnostics.debugDetails,
          ...diagnostics.stack ? { stack: diagnostics.stack } : {}
        });
        task.status = "failed";
        task.error = createTaskError(code, task.kind, diagnostics.details);
        task.updatedAt = nowIso();
      }
      this.failRunningTaskAfterRemoval(task);
      try {
        if (task.status === "completed" && task.result) {
          this.publishManagedMemoryChanged({
            source: "workspace_memory_dream",
            taskId: task.taskId,
            touchedScopes: touchedScopesFromTopics(task.result.touchedTopics),
            ...params.originatorClientId ? { originatorClientId: params.originatorClientId } : {}
          });
        }
      } finally {
        this.evictTerminalTasks();
      }
    }, "run");
    return this.queue(task, run);
  }
  get(taskId, requesterClientId, kind) {
    const task = this.tasks.get(taskId);
    if (!task) return void 0;
    if (kind && task.kind !== kind) return void 0;
    if (task.originatorClientId) {
      if (task.originatorClientId !== requesterClientId) return void 0;
    } else if (requesterClientId) {
      return void 0;
    }
    return cloneTask(task);
  }
};
function validateOriginatorClientId(deps, req, res) {
  const clientId = deps.parseClientId(req, res);
  if (clientId === null) return null;
  if (clientId === void 0) return void 0;
  const known = deps.bridge.knownClientIds();
  if (!known.has(clientId)) {
    res.status(400).json({
      error: `Client id "${clientId}" is not registered for this workspace`,
      code: "invalid_client_id",
      clientId
    });
    return null;
  }
  return clientId;
}
__name(validateOriginatorClientId, "validateOriginatorClientId");
async function validateManagedMemoryAvailable(deps, res, kind) {
  try {
    const available = await deps.bridge.isWorkspaceMemoryRememberAvailable();
    if (!available) {
      res.status(409).json({
        error: "Managed memory is unavailable for this daemon workspace",
        code: "managed_memory_unavailable"
      });
      return false;
    }
    return true;
  } catch (err) {
    debugLogger.error("Availability check failed:", err);
    const code = `${kind}_failed`;
    res.status(500).json({
      error: publicErrorMessage(code, kind),
      code
    });
    return false;
  }
}
__name(validateManagedMemoryAvailable, "validateManagedMemoryAvailable");
function mountWorkspaceMemoryRememberRoutes(app, deps) {
  app.post(
    "/workspace/memory/remember",
    deps.mutate({ strict: true }),
    async (req, res) => {
      const body = deps.safeBody(req);
      const content = body["content"];
      const trimmedContent = typeof content === "string" ? content.trim() : "";
      if (!trimmedContent) {
        res.status(400).json({
          error: "`content` must be a non-empty string",
          code: "invalid_content"
        });
        return;
      }
      if (Buffer.byteLength(trimmedContent, "utf8") > MAX_REMEMBER_CONTENT_BYTES) {
        res.status(400).json({
          error: `\`content\` exceeds the ${MAX_REMEMBER_CONTENT_BYTES}-byte limit`,
          code: "invalid_content"
        });
        return;
      }
      const contextModeRaw = body["contextMode"] ?? "workspace";
      if (contextModeRaw !== "workspace" && contextModeRaw !== "clean") {
        res.status(400).json({
          error: '`contextMode` must be "workspace", "clean", or omitted',
          code: "invalid_context_mode"
        });
        return;
      }
      const originatorClientId = validateOriginatorClientId(deps, req, res);
      if (originatorClientId === null) return;
      if (!await validateManagedMemoryAvailable(deps, res, "remember")) {
        return;
      }
      let task;
      try {
        task = deps.lane.enqueue({
          content: trimmedContent,
          contextMode: contextModeRaw,
          ...originatorClientId ? { originatorClientId } : {}
        });
      } catch (err) {
        const code = workspaceMemoryFailureCode(
          err,
          "remember_failed",
          logWorkspaceMemoryExtractionError
        );
        res.status(publicErrorStatus(code)).json({
          error: publicErrorMessage(code, "remember"),
          code
        });
        return;
      }
      res.status(202).json(task);
    }
  );
  app.get(
    "/workspace/memory/remember/:taskId",
    deps.mutate({ strict: true }),
    (req, res) => {
      const requesterClientId = validateOriginatorClientId(deps, req, res);
      if (requesterClientId === null) return;
      const task = deps.lane.get(
        req.params["taskId"],
        requesterClientId,
        "remember"
      );
      if (!task) {
        res.status(404).json({
          error: "Workspace memory remember task not found",
          code: "remember_task_not_found"
        });
        return;
      }
      res.status(200).json(task);
    }
  );
  app.post(
    "/workspace/memory/forget",
    deps.mutate({ strict: true }),
    async (req, res) => {
      const body = deps.safeBody(req);
      const query = body["query"];
      const trimmedQuery = typeof query === "string" ? query.trim() : "";
      if (!trimmedQuery) {
        res.status(400).json({
          error: "`query` must be a non-empty string",
          code: "invalid_query"
        });
        return;
      }
      if (Buffer.byteLength(trimmedQuery, "utf8") > MAX_REMEMBER_CONTENT_BYTES) {
        res.status(400).json({
          error: `\`query\` exceeds the ${MAX_REMEMBER_CONTENT_BYTES}-byte limit`,
          code: "invalid_query"
        });
        return;
      }
      const originatorClientId = validateOriginatorClientId(deps, req, res);
      if (originatorClientId === null) return;
      if (!await validateManagedMemoryAvailable(deps, res, "forget")) return;
      try {
        const task = deps.lane.enqueueForget({
          query: trimmedQuery,
          ...originatorClientId ? { originatorClientId } : {}
        });
        res.status(202).json(task);
      } catch (err) {
        const code = workspaceMemoryFailureCode(
          err,
          "forget_failed",
          logWorkspaceMemoryExtractionError
        );
        res.status(publicErrorStatus(code)).json({
          error: publicErrorMessage(code, "forget"),
          code
        });
      }
    }
  );
  app.get(
    "/workspace/memory/forget/:taskId",
    deps.mutate({ strict: true }),
    (req, res) => {
      const requesterClientId = validateOriginatorClientId(deps, req, res);
      if (requesterClientId === null) return;
      const task = deps.lane.get(
        req.params["taskId"],
        requesterClientId,
        "forget"
      );
      if (!task) {
        res.status(404).json({
          error: "Workspace memory forget task not found",
          code: "forget_task_not_found"
        });
        return;
      }
      res.status(200).json(task);
    }
  );
  app.post(
    "/workspace/memory/dream",
    deps.mutate({ strict: true }),
    async (req, res) => {
      const originatorClientId = validateOriginatorClientId(deps, req, res);
      if (originatorClientId === null) return;
      if (!await validateManagedMemoryAvailable(deps, res, "dream")) return;
      try {
        const task = deps.lane.enqueueDream({
          ...originatorClientId ? { originatorClientId } : {}
        });
        res.status(202).json(task);
      } catch (err) {
        const code = workspaceMemoryFailureCode(
          err,
          "dream_failed",
          logWorkspaceMemoryExtractionError
        );
        res.status(publicErrorStatus(code)).json({
          error: publicErrorMessage(code, "dream"),
          code
        });
      }
    }
  );
  app.get(
    "/workspace/memory/dream/:taskId",
    deps.mutate({ strict: true }),
    (req, res) => {
      const requesterClientId = validateOriginatorClientId(deps, req, res);
      if (requesterClientId === null) return;
      const task = deps.lane.get(
        req.params["taskId"],
        requesterClientId,
        "dream"
      );
      if (!task) {
        res.status(404).json({
          error: "Workspace memory dream task not found",
          code: "dream_task_not_found"
        });
        return;
      }
      res.status(200).json(task);
    }
  );
}
__name(mountWorkspaceMemoryRememberRoutes, "mountWorkspaceMemoryRememberRoutes");

// packages/cli/src/serve/workspace-memory.ts
init_esbuild_shims();
import { promises as fs } from "node:fs";
import * as path8 from "node:path";

// packages/cli/src/serve/debug-mode.ts
init_esbuild_shims();
function isServeDebugMode() {
  const value = process.env["QWEN_SERVE_DEBUG"];
  if (!value) return false;
  return !["0", "false", "off", "no"].includes(value.trim().toLowerCase());
}
__name(isServeDebugMode, "isServeDebugMode");

// packages/cli/src/serve/workspace-memory.ts
var MAX_MEMORY_CONTENT_BYTES = 1024 * 1024;
function sendWorkspaceMemoryWriteError(res, err, options) {
  const { route, scope, mode } = options;
  if (err instanceof WorkspaceMemoryWriteTimeoutError) {
    writeStderrLine(
      `qwen serve: ${route} timeout \u2014 file lock at ${err.filePath} did not acquire within ${err.timeoutMs}ms (stalled FS / OneDrive / NFS)`
    );
    const debug2 = isServeDebugMode();
    res.status(500).json({
      error: debug2 ? err.message : "Workspace memory write timed out waiting for the per-file lock. Retry or restart the daemon.",
      code: "memory_write_timeout",
      scope,
      mode,
      timeoutMs: err.timeoutMs,
      ...debug2 ? { filePath: err.filePath } : {}
    });
    return;
  }
  if (err instanceof WorkspaceMemoryFileTooLargeError) {
    writeStderrLine(
      `qwen serve: ${route} refused \u2014 existing file ${err.filePath} is ${err.bytes} bytes (cap ${err.limit})`
    );
    const debug2 = isServeDebugMode();
    res.status(413).json({
      error: debug2 ? err.message : "Existing memory file exceeds the safe-append cap. Trim the file or POST with mode=replace.",
      code: "memory_file_too_large",
      scope,
      mode,
      ...debug2 ? { filePath: err.filePath } : {},
      bytes: err.bytes,
      limit: err.limit
    });
    return;
  }
  writeStderrLine(
    `qwen serve: ${route} failed (scope=${scope} mode=${mode}): ${err instanceof Error ? err.stack ?? err.message : String(err)}`
  );
  const osCode = err && typeof err === "object" && "code" in err ? err.code : void 0;
  const debug = isServeDebugMode();
  res.status(500).json({
    error: "Failed to write workspace memory",
    code: "file_error",
    scope,
    mode,
    ...typeof osCode === "string" ? { osCode } : {},
    ...debug ? {
      errorMessage: err instanceof Error ? err.message : String(err)
    } : {}
  });
}
__name(sendWorkspaceMemoryWriteError, "sendWorkspaceMemoryWriteError");
function mountWorkspaceMemoryRoutes(app, deps) {
  app.get("/workspace/memory", async (_req, res) => {
    try {
      const collectStatus = deps.collectStatus ?? collectWorkspaceMemoryStatus;
      const status = await collectStatus(deps.boundWorkspace);
      res.status(200).json(status);
    } catch (err) {
      writeStderrLine(
        `qwen serve: GET /workspace/memory failed: ${err instanceof Error ? err.stack ?? err.message : String(err)}`
      );
      res.status(500).json({
        error: "Failed to discover workspace memory",
        code: "memory_discovery_failed"
      });
    }
  });
  app.post(
    "/workspace/memory",
    deps.mutate({ strict: true }),
    async (req, res) => {
      const body = deps.safeBody(req);
      const scope = body["scope"];
      if (scope !== "workspace" && scope !== "global") {
        res.status(400).json({
          error: '`scope` must be "workspace" or "global"',
          code: "invalid_scope"
        });
        return;
      }
      const modeRaw = body["mode"];
      if (modeRaw !== void 0 && modeRaw !== "append" && modeRaw !== "replace") {
        res.status(400).json({
          error: '`mode` must be "append", "replace", or omitted',
          code: "invalid_mode"
        });
        return;
      }
      const mode = modeRaw === "replace" ? "replace" : "append";
      const content = body["content"];
      if (typeof content !== "string") {
        res.status(400).json({
          error: "`content` must be a string",
          code: "invalid_content"
        });
        return;
      }
      if (Buffer.byteLength(content, "utf8") > MAX_MEMORY_CONTENT_BYTES) {
        res.status(400).json({
          error: `\`content\` exceeds the ${MAX_MEMORY_CONTENT_BYTES}-byte limit`,
          code: "content_too_large"
        });
        return;
      }
      const clientId = deps.parseClientId(req, res);
      if (clientId === null) return;
      let originatorClientId;
      if (clientId !== void 0) {
        const known = deps.bridge.knownClientIds();
        if (!known.has(clientId)) {
          res.status(400).json({
            error: `Client id "${clientId}" is not registered for this workspace`,
            code: "invalid_client_id",
            clientId
          });
          return;
        }
        originatorClientId = clientId;
      }
      try {
        const result = await writeWorkspaceContextFile({
          scope,
          mode,
          content,
          projectRoot: deps.boundWorkspace
        });
        const responseBody = {
          ok: true,
          filePath: result.filePath,
          bytesWritten: result.bytesWritten,
          mode,
          changed: result.changed
        };
        if (result.changed) {
          deps.bridge.publishWorkspaceEvent({
            type: "memory_changed",
            data: {
              scope,
              filePath: result.filePath,
              mode,
              bytesWritten: result.bytesWritten
            },
            ...originatorClientId ? { originatorClientId } : {}
          });
        }
        res.status(200).json(responseBody);
      } catch (err) {
        sendWorkspaceMemoryWriteError(res, err, {
          route: "POST /workspace/memory",
          scope,
          mode
        });
      }
    }
  );
}
__name(mountWorkspaceMemoryRoutes, "mountWorkspaceMemoryRoutes");
function mountWorkspaceQualifiedMemoryRoutes(app, deps) {
  app.get("/workspaces/:workspace/memory", async (req, res) => {
    const runtime = resolveWorkspaceRuntimeFromParam(
      deps.workspaceRegistry,
      req,
      res
    );
    if (!runtime || !requireTrustedWorkspaceRuntime(runtime, res)) return;
    try {
      const collectStatus = deps.collectStatus ?? collectWorkspaceMemoryStatus;
      res.status(200).json(await collectStatus(runtime.workspaceCwd));
    } catch (err) {
      writeStderrLine(
        `qwen serve: GET /workspaces/:workspace/memory failed: ${err instanceof Error ? err.stack ?? err.message : String(err)}`
      );
      res.status(500).json({
        error: "Failed to discover workspace memory",
        code: "memory_discovery_failed"
      });
    }
  });
  app.post(
    "/workspaces/:workspace/memory",
    deps.mutate({ strict: true }),
    async (req, res) => {
      const runtime = resolveWorkspaceRuntimeFromParam(
        deps.workspaceRegistry,
        req,
        res
      );
      if (!runtime || !requireTrustedWorkspaceRuntime(runtime, res)) return;
      const body = deps.safeBody(req);
      if (body["scope"] !== "workspace") {
        res.status(400).json({
          error: 'workspace-qualified memory routes only support "workspace" scope',
          code: "global_scope_not_supported_for_workspace_route"
        });
        return;
      }
      const modeRaw = body["mode"];
      if (modeRaw !== void 0 && modeRaw !== "append" && modeRaw !== "replace") {
        res.status(400).json({
          error: '`mode` must be "append", "replace", or omitted',
          code: "invalid_mode"
        });
        return;
      }
      const mode = modeRaw === "replace" ? "replace" : "append";
      const content = body["content"];
      if (typeof content !== "string") {
        res.status(400).json({
          error: "`content` must be a string",
          code: "invalid_content"
        });
        return;
      }
      if (Buffer.byteLength(content, "utf8") > MAX_MEMORY_CONTENT_BYTES) {
        res.status(400).json({
          error: `\`content\` exceeds the ${MAX_MEMORY_CONTENT_BYTES}-byte limit`,
          code: "content_too_large"
        });
        return;
      }
      const clientId = deps.parseClientId(req, res);
      if (clientId === null) return;
      let originatorClientId;
      if (clientId !== void 0) {
        if (!runtime.bridge.knownClientIds().has(clientId)) {
          res.status(400).json({
            error: `Client id "${clientId}" is not registered for this workspace`,
            code: "invalid_client_id",
            clientId
          });
          return;
        }
        originatorClientId = clientId;
      }
      try {
        const result = await writeWorkspaceContextFile({
          scope: "workspace",
          mode,
          content,
          projectRoot: runtime.workspaceCwd
        });
        if (result.changed) {
          runtime.bridge.publishWorkspaceEvent({
            type: "memory_changed",
            data: {
              scope: "workspace",
              filePath: result.filePath,
              mode,
              bytesWritten: result.bytesWritten
            },
            ...originatorClientId ? { originatorClientId } : {}
          });
        }
        res.status(200).json({
          ok: true,
          filePath: result.filePath,
          bytesWritten: result.bytesWritten,
          mode,
          changed: result.changed
        });
      } catch (err) {
        sendWorkspaceMemoryWriteError(res, err, {
          route: "POST /workspaces/:workspace/memory",
          scope: "workspace",
          mode
        });
      }
    }
  );
}
__name(mountWorkspaceQualifiedMemoryRoutes, "mountWorkspaceQualifiedMemoryRoutes");
async function collectWorkspaceMemoryStatus(boundWorkspace) {
  const filenames = new Set(getAllGeminiMdFilenames());
  const files = [];
  const errors = [];
  const workspaceFiles = await walkWorkspaceForMemory(
    boundWorkspace,
    filenames,
    errors
  );
  files.push(...workspaceFiles);
  const globalDir = Storage.getGlobalQwenDir();
  for (const filename of filenames) {
    const candidate = path8.join(globalDir, filename);
    try {
      const stat2 = await fs.stat(candidate);
      if (stat2.isFile()) {
        files.push({
          absolutePath: candidate,
          scope: "global",
          bytes: stat2.size
        });
      }
    } catch (err) {
      if (!isEnoent(err)) {
        errors.push({
          kind: "memory_file",
          status: "error",
          error: err instanceof Error ? err.message : String(err),
          errorKind: "stat_failed",
          hint: candidate
        });
      }
    }
  }
  if (files.length === 0 && errors.length === 0) {
    return createIdleWorkspaceMemoryStatus(boundWorkspace);
  }
  const totalBytes = files.reduce((acc, f) => acc + f.bytes, 0);
  const result = {
    v: STATUS_SCHEMA_VERSION,
    workspaceCwd: boundWorkspace,
    initialized: true,
    files: files.map(
      (f) => ({
        kind: "memory_file",
        path: f.absolutePath,
        scope: f.scope,
        bytes: f.bytes
      })
    ),
    totalBytes,
    fileCount: files.length,
    ruleCount: 0
  };
  if (errors.length > 0) result.errors = errors;
  return result;
}
__name(collectWorkspaceMemoryStatus, "collectWorkspaceMemoryStatus");
async function walkWorkspaceForMemory(start, filenames, errors) {
  const out = [];
  for (const filename of filenames) {
    const candidate = path8.join(start, filename);
    try {
      const stat2 = await fs.stat(candidate);
      if (stat2.isFile()) {
        out.push({
          absolutePath: candidate,
          scope: "workspace",
          bytes: stat2.size
        });
      }
    } catch (err) {
      if (!isEnoent(err)) {
        errors.push({
          kind: "memory_file",
          status: "error",
          error: err instanceof Error ? err.message : String(err),
          errorKind: "stat_failed",
          hint: candidate
        });
      }
    }
  }
  return out;
}
__name(walkWorkspaceForMemory, "walkWorkspaceForMemory");
function isEnoent(err) {
  return typeof err === "object" && err !== null && err.code === "ENOENT";
}
__name(isEnoent, "isEnoent");

// packages/cli/src/serve/workspace-agents.ts
init_esbuild_shims();
import { promises as fs2 } from "node:fs";
var AGENT_TYPE_PATTERN = /^[\p{L}\p{N}_-]+$/u;
var AGENT_TYPE_MAX_LENGTH = 64;
var AGENT_TYPE_MIN_LENGTH = 2;
var MAX_DESCRIPTION_BYTES = 256 * 1024;
var MAX_SYSTEM_PROMPT_BYTES = 256 * 1024;
var MAX_TOOLS_ENTRIES = 256;
var MAX_TOOL_ID_LENGTH = 256;
function mountWorkspaceAgentsRoutes(app, deps) {
  const manager = createDaemonSubagentManager(deps.boundWorkspace);
  app.get("/workspace/agents", async (_req, res) => {
    try {
      const agents = await manager.listSubagents({ force: true });
      const status = {
        v: STATUS_SCHEMA_VERSION,
        workspaceCwd: deps.boundWorkspace,
        agents: agents.map(toSummary)
      };
      res.status(200).json(status);
    } catch (err) {
      writeStderrLine(
        `qwen serve: GET /workspace/agents failed: ${err instanceof Error ? err.stack ?? err.message : String(err)}`
      );
      res.status(500).json({
        error: "Failed to list workspace agents",
        code: "agent_list_failed"
      });
    }
  });
  app.post(
    "/workspace/agents",
    deps.mutate({ strict: true }),
    async (req, res) => {
      const body = deps.safeBody(req);
      const clientIdResult = resolveOriginatorClientId(deps, req, res);
      if (clientIdResult === null) return;
      const originatorClientId = clientIdResult;
      const scope = body["scope"];
      if (scope !== "workspace" && scope !== "global") {
        res.status(400).json({
          error: '`scope` must be "workspace" or "global"',
          code: "invalid_scope"
        });
        return;
      }
      const level = scope === "workspace" ? "project" : "user";
      const config = parseAgentConfig(body, level, res);
      if (!config) return;
      const collision = await manager.loadSubagent(config.name, level);
      if (collision) {
        res.status(409).json({
          error: `Subagent "${config.name}" already exists at ${level} level`,
          code: "agent_already_exists",
          name: config.name,
          level
        });
        return;
      }
      try {
        await manager.createSubagent(config, { level });
      } catch (err) {
        if (err instanceof SubagentError) {
          if (err.code === SubagentErrorCode.ALREADY_EXISTS) {
            res.status(409).json({
              error: err.message,
              code: "agent_already_exists",
              name: err.subagentName ?? config.name
            });
            return;
          }
          if (err.code === SubagentErrorCode.VALIDATION_ERROR || err.code === SubagentErrorCode.INVALID_CONFIG || err.code === SubagentErrorCode.INVALID_NAME || err.code === SubagentErrorCode.TOOL_NOT_FOUND) {
            res.status(422).json({
              error: err.message,
              code: "invalid_config",
              name: err.subagentName ?? config.name
            });
            return;
          }
          if (err.code === SubagentErrorCode.FILE_ERROR) {
            const debug = isServeDebugMode();
            res.status(500).json({
              error: debug ? err.message : "Failed to write workspace agent file",
              code: "file_error",
              name: err.subagentName ?? config.name
            });
            return;
          }
        }
        writeStderrLine(
          `qwen serve: POST /workspace/agents failed: ${err instanceof Error ? err.stack ?? err.message : String(err)}`
        );
        res.status(500).json({
          error: "Failed to create workspace agent",
          code: "agent_create_failed"
        });
        return;
      }
      const created = await manager.loadSubagent(config.name, level);
      if (!created) {
        writeStderrLine(
          `qwen serve: agent_create_reload_failed (name=${safeLogValue(config.name)} level=${level}) \u2014 file likely persisted on disk; check \`GET /workspace/agents\` for a phantom entry`
        );
        res.status(500).json({
          error: "Agent creation succeeded but reload failed",
          code: "agent_create_reload_failed",
          name: config.name,
          level
        });
        return;
      }
      deps.bridge.publishWorkspaceEvent({
        type: "agent_changed",
        data: { change: "created", name: config.name, level },
        ...originatorClientId ? { originatorClientId } : {}
      });
      res.status(201).json({ ok: true, agent: toDetail(created) });
    }
  );
  app.post(
    "/workspace/agents/generate",
    deps.mutate({ strict: true }),
    async (req, res) => {
      const body = deps.safeBody(req);
      const clientIdResult = resolveOriginatorClientId(deps, req, res);
      if (clientIdResult === null) return;
      const originatorClientId = clientIdResult;
      const description = body["description"];
      if (typeof description !== "string" || description.trim().length === 0) {
        res.status(400).json({
          error: "`description` must be a non-empty string",
          code: "invalid_description"
        });
        return;
      }
      if (Buffer.byteLength(description, "utf8") > 4096) {
        res.status(400).json({
          error: "`description` exceeds the 4096-byte limit",
          code: "invalid_description"
        });
        return;
      }
      try {
        const generated = await deps.bridge.generateWorkspaceAgent(
          description.trim(),
          originatorClientId
        );
        res.status(200).json(generated);
      } catch (err) {
        writeStderrLine(
          `qwen serve: POST /workspace/agents/generate failed: ${err instanceof Error ? err.stack ?? err.message : String(err)}`
        );
        res.status(500).json({
          error: "Failed to generate workspace agent",
          code: "agent_generate_failed"
        });
      }
    }
  );
  app.get("/workspace/agents/:agentType", async (req, res) => {
    const agentType = validateAgentType(req, res);
    if (agentType === null) return;
    try {
      const config = await manager.loadSubagent(agentType);
      if (!config) {
        res.status(404).json({
          error: `Subagent "${agentType}" not found`,
          code: "agent_not_found",
          name: agentType
        });
        return;
      }
      res.status(200).json(toDetail(config));
    } catch (err) {
      writeStderrLine(
        `qwen serve: GET /workspace/agents/${safeLogValue(agentType)} failed: ${err instanceof Error ? err.stack ?? err.message : String(err)}`
      );
      res.status(500).json({
        error: "Failed to read workspace agent",
        code: "agent_read_failed"
      });
    }
  });
  app.post(
    "/workspace/agents/:agentType",
    deps.mutate({ strict: true }),
    async (req, res) => {
      const agentType = validateAgentType(req, res);
      if (agentType === null) return;
      const clientIdResult = resolveOriginatorClientId(deps, req, res);
      if (clientIdResult === null) return;
      const originatorClientId = clientIdResult;
      const body = deps.safeBody(req);
      const updates = parseAgentUpdates(body, res);
      if (!updates) return;
      const preferredLevel = parseScopeQuery(req, res);
      if (preferredLevel === null) return;
      const existing = await manager.loadSubagent(agentType, preferredLevel);
      if (!existing) {
        res.status(404).json({
          error: `Subagent "${agentType}" not found`,
          code: "agent_not_found",
          name: agentType
        });
        return;
      }
      if (assertMutableLevel(existing, agentType, res)) {
        return;
      }
      if (Object.keys(updates).length === 0) {
        res.status(400).json({
          error: "`POST /workspace/agents/:agentType` requires at least one updatable field in the body",
          code: "invalid_config",
          name: agentType
        });
        return;
      }
      if (isNoOpUpdate(existing, updates)) {
        res.status(200).json({
          ok: true,
          agent: toDetail(existing),
          changed: false
        });
        return;
      }
      try {
        await manager.updateSubagent(agentType, updates, existing.level);
      } catch (err) {
        if (err instanceof SubagentError) {
          if (err.code === SubagentErrorCode.NOT_FOUND) {
            res.status(404).json({
              error: err.message,
              code: "agent_not_found",
              name: err.subagentName ?? agentType
            });
            return;
          }
          if (err.code === SubagentErrorCode.INVALID_CONFIG) {
            res.status(403).json({
              error: err.message,
              code: "agent_readonly",
              name: err.subagentName ?? agentType
            });
            return;
          }
          if (err.code === SubagentErrorCode.VALIDATION_ERROR || err.code === SubagentErrorCode.INVALID_NAME || err.code === SubagentErrorCode.TOOL_NOT_FOUND) {
            res.status(422).json({
              error: err.message,
              code: "invalid_config",
              name: err.subagentName ?? agentType
            });
            return;
          }
          if (err.code === SubagentErrorCode.FILE_ERROR) {
            const debug = isServeDebugMode();
            res.status(500).json({
              error: debug ? err.message : "Failed to write workspace agent file",
              code: "file_error",
              name: err.subagentName ?? agentType
            });
            return;
          }
        }
        writeStderrLine(
          `qwen serve: POST /workspace/agents/${safeLogValue(agentType)} failed: ${err instanceof Error ? err.stack ?? err.message : String(err)}`
        );
        res.status(500).json({
          error: "Failed to update workspace agent",
          code: "agent_update_failed"
        });
        return;
      }
      const updated = await manager.loadSubagent(agentType, existing.level);
      if (!updated) {
        writeStderrLine(
          `qwen serve: agent_update_reload_failed (name=${safeLogValue(agentType)} level=${existing.level}) \u2014 disk write completed; check \`GET /workspace/agents/${safeLogValue(agentType)}\` for the new state`
        );
        res.status(500).json({
          error: "Agent update succeeded but reload failed",
          code: "agent_update_reload_failed",
          name: agentType,
          level: existing.level
        });
        return;
      }
      const eventLevel = existing.level === "project" ? "project" : "user";
      deps.bridge.publishWorkspaceEvent({
        type: "agent_changed",
        data: { change: "updated", name: existing.name, level: eventLevel },
        ...originatorClientId ? { originatorClientId } : {}
      });
      res.status(200).json({ ok: true, agent: toDetail(updated), changed: true });
    }
  );
  app.delete(
    "/workspace/agents/:agentType",
    deps.mutate({ strict: true }),
    async (req, res) => {
      const agentType = validateAgentType(req, res);
      if (agentType === null) return;
      const clientIdResult = resolveOriginatorClientId(deps, req, res);
      if (clientIdResult === null) return;
      const originatorClientId = clientIdResult;
      const scopedLevel = parseScopeQuery(req, res);
      if (scopedLevel === null) return;
      const levelsToCheck = scopedLevel ? [scopedLevel] : ["project", "user"];
      const existingAtLevels = [];
      for (const lvl of levelsToCheck) {
        const found = await manager.loadSubagent(agentType, lvl);
        if (found) existingAtLevels.push(found);
      }
      for (const found of existingAtLevels) {
        if (assertMutableLevel(found, agentType, res)) return;
      }
      try {
        await manager.deleteSubagent(agentType, scopedLevel);
      } catch (err) {
        if (err instanceof SubagentError) {
          if (err.code === SubagentErrorCode.NOT_FOUND) {
            res.status(404).json({
              error: err.message,
              code: "agent_not_found",
              name: err.subagentName ?? agentType
            });
            return;
          }
          if (err.code === SubagentErrorCode.INVALID_CONFIG) {
            res.status(403).json({
              error: err.message,
              code: "agent_readonly",
              name: err.subagentName ?? agentType
            });
            return;
          }
        }
        writeStderrLine(
          `qwen serve: DELETE /workspace/agents/${safeLogValue(agentType)} failed: ${err instanceof Error ? err.stack ?? err.message : String(err)}`
        );
        res.status(500).json({
          error: "Failed to delete workspace agent",
          code: "agent_delete_failed"
        });
        return;
      }
      const removed = [];
      const remaining = [];
      for (const found of existingAtLevels) {
        if (!found.filePath) {
          removed.push(found);
          continue;
        }
        try {
          await fs2.access(found.filePath);
          remaining.push(found);
        } catch {
          removed.push(found);
        }
      }
      if (remaining.length > 0) {
        writeStderrLine(
          `qwen serve: DELETE /workspace/agents/${safeLogValue(agentType)} partial \u2014 removed=${removed.map((r) => r.level).join(",") || "none"} remaining=${remaining.map((r) => `${r.level}:${r.filePath}`).join(",")}`
        );
        for (const found of removed) {
          const evtLevel = found.level === "project" ? "project" : "user";
          deps.bridge.publishWorkspaceEvent({
            type: "agent_changed",
            data: {
              change: "deleted",
              name: found.name,
              level: evtLevel
            },
            ...originatorClientId ? { originatorClientId } : {}
          });
        }
        res.status(500).json({
          error: `Failed to delete every level of subagent "${agentType}" \u2014 ${remaining.length} level(s) still have their file on disk`,
          code: "agent_delete_partial",
          name: agentType,
          removedLevels: removed.map((r) => r.level),
          remainingLevels: remaining.map((r) => r.level)
        });
        return;
      }
      if (existingAtLevels.length === 0) {
        const fallbackLevel = scopedLevel === "user" ? "user" : "project";
        deps.bridge.publishWorkspaceEvent({
          type: "agent_changed",
          data: {
            change: "deleted",
            name: agentType,
            level: fallbackLevel
          },
          ...originatorClientId ? { originatorClientId } : {}
        });
      } else {
        for (const found of removed) {
          const evtLevel = found.level === "project" ? "project" : "user";
          deps.bridge.publishWorkspaceEvent({
            type: "agent_changed",
            data: {
              change: "deleted",
              name: found.name,
              level: evtLevel
            },
            ...originatorClientId ? { originatorClientId } : {}
          });
        }
      }
      res.status(204).end();
    }
  );
}
__name(mountWorkspaceAgentsRoutes, "mountWorkspaceAgentsRoutes");
function mountWorkspaceQualifiedAgentsRoutes(app, deps) {
  app.get("/workspaces/:workspace/agents", async (req, res) => {
    const runtime = resolveTrustedWorkspaceAgentRuntime(deps, req, res);
    if (!runtime) return;
    const scopedLevel = parseWorkspaceOnlyAgentScopeQuery(req, res);
    if (scopedLevel === null) return;
    const manager = createDaemonSubagentManager(runtime.workspaceCwd);
    try {
      const agents = await manager.listSubagents({ force: true });
      const status = {
        v: STATUS_SCHEMA_VERSION,
        workspaceCwd: runtime.workspaceCwd,
        agents: agents.filter((agent) => agent.level === "project").map(toSummary)
      };
      res.status(200).json(status);
    } catch (err) {
      writeStderrLine(
        `qwen serve: GET /workspaces/:workspace/agents failed: ${err instanceof Error ? err.stack ?? err.message : String(err)}`
      );
      res.status(500).json({
        error: "Failed to list workspace agents",
        code: "agent_list_failed"
      });
    }
  });
  app.post(
    "/workspaces/:workspace/agents",
    deps.mutate({ strict: true }),
    async (req, res) => {
      const runtime = resolveTrustedWorkspaceAgentRuntime(deps, req, res);
      if (!runtime) return;
      const routeDeps = workspaceAgentDepsForRuntime(runtime, deps);
      const body = deps.safeBody(req);
      const clientIdResult = resolveOriginatorClientId(routeDeps, req, res);
      if (clientIdResult === null) return;
      const originatorClientId = clientIdResult;
      const level = parseWorkspaceOnlyAgentBodyScope(body, res);
      if (level === null) return;
      const manager = createDaemonSubagentManager(runtime.workspaceCwd);
      const config = parseAgentConfig(body, level, res);
      if (!config) return;
      const collision = await manager.loadSubagent(config.name, level);
      if (collision) {
        res.status(409).json({
          error: `Subagent "${config.name}" already exists at ${level} level`,
          code: "agent_already_exists",
          name: config.name,
          level
        });
        return;
      }
      try {
        await manager.createSubagent(config, { level });
      } catch (err) {
        if (sendCreateAgentError(res, err, config.name)) return;
        writeStderrLine(
          `qwen serve: POST /workspaces/:workspace/agents failed: ${err instanceof Error ? err.stack ?? err.message : String(err)}`
        );
        res.status(500).json({
          error: "Failed to create workspace agent",
          code: "agent_create_failed"
        });
        return;
      }
      const created = await manager.loadSubagent(config.name, level);
      if (!created) {
        writeStderrLine(
          `qwen serve: agent_create_reload_failed (name=${safeLogValue(config.name)} level=${level}) \u2014 file likely persisted on disk; check \`GET /workspaces/:workspace/agents\` for a phantom entry`
        );
        res.status(500).json({
          error: "Agent creation succeeded but reload failed",
          code: "agent_create_reload_failed",
          name: config.name,
          level
        });
        return;
      }
      runtime.bridge.publishWorkspaceEvent({
        type: "agent_changed",
        data: { change: "created", name: config.name, level: "project" },
        ...originatorClientId ? { originatorClientId } : {}
      });
      res.status(201).json({ ok: true, agent: toDetail(created) });
    }
  );
  app.get("/workspaces/:workspace/agents/:agentType", async (req, res) => {
    const runtime = resolveTrustedWorkspaceAgentRuntime(deps, req, res);
    if (!runtime) return;
    const agentType = validateAgentType(req, res);
    if (agentType === null) return;
    const scopedLevel = parseWorkspaceOnlyAgentScopeQuery(req, res);
    if (scopedLevel === null) return;
    const manager = createDaemonSubagentManager(runtime.workspaceCwd);
    try {
      const config = await manager.loadSubagent(agentType, scopedLevel);
      if (!config) {
        res.status(404).json({
          error: `Subagent "${agentType}" not found`,
          code: "agent_not_found",
          name: agentType
        });
        return;
      }
      res.status(200).json(toDetail(config));
    } catch (err) {
      writeStderrLine(
        `qwen serve: GET /workspaces/:workspace/agents/${safeLogValue(agentType)} failed: ${err instanceof Error ? err.stack ?? err.message : String(err)}`
      );
      res.status(500).json({
        error: "Failed to read workspace agent",
        code: "agent_read_failed"
      });
    }
  });
  app.post(
    "/workspaces/:workspace/agents/:agentType",
    deps.mutate({ strict: true }),
    async (req, res) => {
      const runtime = resolveTrustedWorkspaceAgentRuntime(deps, req, res);
      if (!runtime) return;
      const agentType = validateAgentType(req, res);
      if (agentType === null) return;
      const scopedLevel = parseWorkspaceOnlyAgentScopeQuery(req, res);
      if (scopedLevel === null) return;
      const routeDeps = workspaceAgentDepsForRuntime(runtime, deps);
      const clientIdResult = resolveOriginatorClientId(routeDeps, req, res);
      if (clientIdResult === null) return;
      const originatorClientId = clientIdResult;
      const body = deps.safeBody(req);
      const updates = parseAgentUpdates(body, res);
      if (!updates) return;
      const manager = createDaemonSubagentManager(runtime.workspaceCwd);
      const existing = await manager.loadSubagent(agentType, scopedLevel);
      if (!existing) {
        res.status(404).json({
          error: `Subagent "${agentType}" not found`,
          code: "agent_not_found",
          name: agentType
        });
        return;
      }
      if (assertMutableLevel(existing, agentType, res)) return;
      if (Object.keys(updates).length === 0) {
        res.status(400).json({
          error: "`POST /workspaces/:workspace/agents/:agentType` requires at least one updatable field in the body",
          code: "invalid_config",
          name: agentType
        });
        return;
      }
      if (isNoOpUpdate(existing, updates)) {
        res.status(200).json({
          ok: true,
          agent: toDetail(existing),
          changed: false
        });
        return;
      }
      try {
        await manager.updateSubagent(agentType, updates, existing.level);
      } catch (err) {
        if (sendUpdateAgentError(res, err, agentType)) return;
        writeStderrLine(
          `qwen serve: POST /workspaces/:workspace/agents/${safeLogValue(agentType)} failed: ${err instanceof Error ? err.stack ?? err.message : String(err)}`
        );
        res.status(500).json({
          error: "Failed to update workspace agent",
          code: "agent_update_failed"
        });
        return;
      }
      const updated = await manager.loadSubagent(agentType, existing.level);
      if (!updated) {
        writeStderrLine(
          `qwen serve: agent_update_reload_failed (name=${safeLogValue(agentType)} level=${existing.level}) \u2014 disk write completed; check \`GET /workspaces/:workspace/agents/${safeLogValue(agentType)}\` for the new state`
        );
        res.status(500).json({
          error: "Agent update succeeded but reload failed",
          code: "agent_update_reload_failed",
          name: agentType,
          level: existing.level
        });
        return;
      }
      runtime.bridge.publishWorkspaceEvent({
        type: "agent_changed",
        data: { change: "updated", name: existing.name, level: "project" },
        ...originatorClientId ? { originatorClientId } : {}
      });
      res.status(200).json({ ok: true, agent: toDetail(updated), changed: true });
    }
  );
  app.delete(
    "/workspaces/:workspace/agents/:agentType",
    deps.mutate({ strict: true }),
    async (req, res) => {
      const runtime = resolveTrustedWorkspaceAgentRuntime(deps, req, res);
      if (!runtime) return;
      const agentType = validateAgentType(req, res);
      if (agentType === null) return;
      const scopedLevel = parseWorkspaceOnlyAgentScopeQuery(req, res);
      if (scopedLevel === null) return;
      const routeDeps = workspaceAgentDepsForRuntime(runtime, deps);
      const clientIdResult = resolveOriginatorClientId(routeDeps, req, res);
      if (clientIdResult === null) return;
      const originatorClientId = clientIdResult;
      const manager = createDaemonSubagentManager(runtime.workspaceCwd);
      const existing = await manager.loadSubagent(agentType, scopedLevel);
      if (existing && assertMutableLevel(existing, agentType, res)) return;
      try {
        await manager.deleteSubagent(agentType, scopedLevel);
      } catch (err) {
        if (err instanceof SubagentError) {
          if (err.code === SubagentErrorCode.NOT_FOUND) {
            res.status(404).json({
              error: err.message,
              code: "agent_not_found",
              name: err.subagentName ?? agentType
            });
            return;
          }
          if (err.code === SubagentErrorCode.INVALID_CONFIG) {
            res.status(403).json({
              error: err.message,
              code: "agent_readonly",
              name: err.subagentName ?? agentType
            });
            return;
          }
        }
        writeStderrLine(
          `qwen serve: DELETE /workspaces/:workspace/agents/${safeLogValue(agentType)} failed: ${err instanceof Error ? err.stack ?? err.message : String(err)}`
        );
        res.status(500).json({
          error: "Failed to delete workspace agent",
          code: "agent_delete_failed"
        });
        return;
      }
      if (existing?.filePath) {
        try {
          await fs2.access(existing.filePath);
          writeStderrLine(
            `qwen serve: DELETE /workspaces/:workspace/agents/${safeLogValue(agentType)} partial \u2014 remaining=${existing.level}:${existing.filePath}`
          );
          res.status(500).json({
            error: `Failed to delete subagent "${agentType}" \u2014 ${existing.level} level still has its file on disk`,
            code: "agent_delete_partial",
            name: agentType,
            removedLevels: [],
            remainingLevels: [existing.level]
          });
          return;
        } catch {
        }
      }
      runtime.bridge.publishWorkspaceEvent({
        type: "agent_changed",
        data: {
          change: "deleted",
          name: existing?.name ?? agentType,
          level: "project"
        },
        ...originatorClientId ? { originatorClientId } : {}
      });
      res.status(204).end();
    }
  );
}
__name(mountWorkspaceQualifiedAgentsRoutes, "mountWorkspaceQualifiedAgentsRoutes");
function validateAgentType(req, res) {
  const raw = req.params["agentType"];
  if (!raw || raw.length === 0) {
    res.status(400).json({
      error: "`agentType` path parameter is required",
      code: "invalid_agent_type"
    });
    return null;
  }
  if (raw.length > AGENT_TYPE_MAX_LENGTH || !AGENT_TYPE_PATTERN.test(raw)) {
    res.status(400).json({
      error: "`agentType` must contain only letters, numbers, hyphens, or underscores (max 64 chars)",
      code: "invalid_agent_type",
      agentType: raw
    });
    return null;
  }
  return raw;
}
__name(validateAgentType, "validateAgentType");
function parseScopeQuery(req, res) {
  const raw = req.query["scope"];
  if (raw === void 0) return void 0;
  if (typeof raw !== "string") {
    res.status(400).json({
      error: '`scope` query must be a single "workspace" or "global" value',
      code: "invalid_scope"
    });
    return null;
  }
  if (raw !== "workspace" && raw !== "global") {
    res.status(400).json({
      error: '`scope` query must be "workspace" or "global"',
      code: "invalid_scope"
    });
    return null;
  }
  return raw === "workspace" ? "project" : "user";
}
__name(parseScopeQuery, "parseScopeQuery");
function assertMutableLevel(found, agentType, res) {
  if (found.isBuiltin || found.level === "builtin" || found.level === "extension" || found.level === "session") {
    res.status(403).json({
      error: `Cannot modify ${found.level}-level subagent "${agentType}"`,
      code: "agent_readonly",
      name: found.name,
      level: found.level
    });
    return true;
  }
  return false;
}
__name(assertMutableLevel, "assertMutableLevel");
function resolveOriginatorClientId(deps, req, res) {
  const clientId = deps.parseClientId(req, res);
  if (clientId === null) return null;
  if (clientId === void 0) return void 0;
  if (!deps.bridge.knownClientIds().has(clientId)) {
    res.status(400).json({
      error: `Client id "${clientId}" is not registered for this workspace`,
      code: "invalid_client_id",
      clientId
    });
    return null;
  }
  return clientId;
}
__name(resolveOriginatorClientId, "resolveOriginatorClientId");
function resolveTrustedWorkspaceAgentRuntime(deps, req, res) {
  const runtime = resolveWorkspaceRuntimeFromParam(
    deps.workspaceRegistry,
    req,
    res
  );
  if (!runtime) return void 0;
  if (!requireTrustedWorkspaceRuntime(runtime, res)) return void 0;
  return runtime;
}
__name(resolveTrustedWorkspaceAgentRuntime, "resolveTrustedWorkspaceAgentRuntime");
function workspaceAgentDepsForRuntime(runtime, deps) {
  return {
    bridge: runtime.bridge,
    boundWorkspace: runtime.workspaceCwd,
    mutate: deps.mutate,
    parseClientId: deps.parseClientId,
    safeBody: deps.safeBody
  };
}
__name(workspaceAgentDepsForRuntime, "workspaceAgentDepsForRuntime");
function parseWorkspaceOnlyAgentBodyScope(body, res) {
  const scope = body["scope"];
  if (scope === void 0 || scope === "workspace" || scope === "project") {
    return "project";
  }
  return rejectWorkspaceQualifiedAgentScope(scope, res);
}
__name(parseWorkspaceOnlyAgentBodyScope, "parseWorkspaceOnlyAgentBodyScope");
function parseWorkspaceOnlyAgentScopeQuery(req, res) {
  const raw = req.query["scope"];
  if (raw === void 0 || raw === "workspace" || raw === "project") {
    return "project";
  }
  if (typeof raw !== "string") {
    res.status(400).json({
      error: "`scope` query must be a single workspace/project value",
      code: "invalid_scope"
    });
    return null;
  }
  return rejectWorkspaceQualifiedAgentScope(raw, res);
}
__name(parseWorkspaceOnlyAgentScopeQuery, "parseWorkspaceOnlyAgentScopeQuery");
function rejectWorkspaceQualifiedAgentScope(scope, res) {
  if (scope === "global" || scope === "user") {
    res.status(400).json({
      error: "Workspace-qualified agents routes only support workspace/project scope",
      code: "global_scope_not_supported_for_workspace_route"
    });
    return null;
  }
  res.status(400).json({
    error: '`scope` must be "workspace" or "project"',
    code: "invalid_scope"
  });
  return null;
}
__name(rejectWorkspaceQualifiedAgentScope, "rejectWorkspaceQualifiedAgentScope");
function sendCreateAgentError(res, err, name) {
  if (!(err instanceof SubagentError)) return false;
  if (err.code === SubagentErrorCode.ALREADY_EXISTS) {
    res.status(409).json({
      error: err.message,
      code: "agent_already_exists",
      name: err.subagentName ?? name
    });
    return true;
  }
  if (err.code === SubagentErrorCode.VALIDATION_ERROR || err.code === SubagentErrorCode.INVALID_CONFIG || err.code === SubagentErrorCode.INVALID_NAME || err.code === SubagentErrorCode.TOOL_NOT_FOUND) {
    res.status(422).json({
      error: err.message,
      code: "invalid_config",
      name: err.subagentName ?? name
    });
    return true;
  }
  if (err.code === SubagentErrorCode.FILE_ERROR) {
    const debug = isServeDebugMode();
    res.status(500).json({
      error: debug ? err.message : "Failed to write workspace agent file",
      code: "file_error",
      name: err.subagentName ?? name
    });
    return true;
  }
  return false;
}
__name(sendCreateAgentError, "sendCreateAgentError");
function sendUpdateAgentError(res, err, agentType) {
  if (!(err instanceof SubagentError)) return false;
  if (err.code === SubagentErrorCode.NOT_FOUND) {
    res.status(404).json({
      error: err.message,
      code: "agent_not_found",
      name: err.subagentName ?? agentType
    });
    return true;
  }
  if (err.code === SubagentErrorCode.INVALID_CONFIG) {
    res.status(403).json({
      error: err.message,
      code: "agent_readonly",
      name: err.subagentName ?? agentType
    });
    return true;
  }
  if (err.code === SubagentErrorCode.VALIDATION_ERROR || err.code === SubagentErrorCode.INVALID_NAME || err.code === SubagentErrorCode.TOOL_NOT_FOUND) {
    res.status(422).json({
      error: err.message,
      code: "invalid_config",
      name: err.subagentName ?? agentType
    });
    return true;
  }
  if (err.code === SubagentErrorCode.FILE_ERROR) {
    const debug = isServeDebugMode();
    res.status(500).json({
      error: debug ? err.message : "Failed to write workspace agent file",
      code: "file_error",
      name: err.subagentName ?? agentType
    });
    return true;
  }
  return false;
}
__name(sendUpdateAgentError, "sendUpdateAgentError");
function parseAgentConfig(body, level, res) {
  const rawName = body["name"];
  if (typeof rawName !== "string" || rawName.trim().length === 0) {
    res.status(422).json({
      error: "`name` is required and must be a non-empty string",
      code: "invalid_config"
    });
    return void 0;
  }
  const name = rawName.trim();
  if (name.length < AGENT_TYPE_MIN_LENGTH || name.length > AGENT_TYPE_MAX_LENGTH || !AGENT_TYPE_PATTERN.test(name)) {
    res.status(422).json({
      error: `\`name\` must be ${AGENT_TYPE_MIN_LENGTH}-${AGENT_TYPE_MAX_LENGTH} characters of letters, numbers, hyphens, or underscores`,
      code: "invalid_config",
      name
    });
    return void 0;
  }
  if (BuiltinAgentRegistry.isBuiltinAgent(name)) {
    res.status(422).json({
      error: `"${name}" shadows a built-in subagent and cannot be used as a project- or user-level agent name. Choose a different name.`,
      code: "invalid_config",
      name
    });
    return void 0;
  }
  const description = body["description"];
  if (typeof description !== "string" || description.trim().length === 0) {
    res.status(422).json({
      error: "`description` is required and must be a non-empty string",
      code: "invalid_config"
    });
    return void 0;
  }
  if (Buffer.byteLength(description, "utf8") > MAX_DESCRIPTION_BYTES) {
    res.status(422).json({
      error: `\`description\` exceeds the ${MAX_DESCRIPTION_BYTES}-byte limit`,
      code: "invalid_config"
    });
    return void 0;
  }
  const systemPrompt = body["systemPrompt"];
  if (typeof systemPrompt !== "string" || systemPrompt.trim().length === 0) {
    res.status(422).json({
      error: "`systemPrompt` is required and must be a non-empty string (whitespace only is rejected)",
      code: "invalid_config"
    });
    return void 0;
  }
  if (Buffer.byteLength(systemPrompt, "utf8") > MAX_SYSTEM_PROMPT_BYTES) {
    res.status(422).json({
      error: `\`systemPrompt\` exceeds the ${MAX_SYSTEM_PROMPT_BYTES}-byte limit`,
      code: "invalid_config"
    });
    return void 0;
  }
  const tools = parseStringArray(body["tools"], "tools", res);
  if (tools === null) return void 0;
  const disallowedTools = parseStringArray(
    body["disallowedTools"],
    "disallowedTools",
    res
  );
  if (disallowedTools === null) return void 0;
  const config = {
    name,
    description,
    systemPrompt,
    level
  };
  if (tools !== void 0) config.tools = tools;
  if (disallowedTools !== void 0) config.disallowedTools = disallowedTools;
  if (rejectIfPresentWrongType(body, "model", "string", res)) return void 0;
  if (typeof body["model"] === "string") config.model = body["model"];
  if (rejectIfPresentWrongType(body, "color", "string", res)) return void 0;
  if (typeof body["color"] === "string") config.color = body["color"];
  if (rejectIfPresentWrongType(body, "approvalMode", "string", res)) {
    return void 0;
  }
  if (typeof body["approvalMode"] === "string") {
    if (!APPROVAL_MODES.includes(body["approvalMode"])) {
      res.status(422).json({
        error: `\`approvalMode\` must be one of ${JSON.stringify(APPROVAL_MODES)}`,
        code: "invalid_config"
      });
      return void 0;
    }
    config.approvalMode = body["approvalMode"];
  }
  if (rejectIfPresentWrongType(body, "background", "boolean", res)) {
    return void 0;
  }
  if (typeof body["background"] === "boolean") {
    config.background = body["background"];
  }
  const runConfig = body["runConfig"];
  if (runConfig !== void 0) {
    const sanitized = sanitizeRunConfig(runConfig, res);
    if (sanitized === null) return void 0;
    config.runConfig = sanitized;
  }
  return config;
}
__name(parseAgentConfig, "parseAgentConfig");
function parseAgentUpdates(body, res) {
  const updates = {};
  if ("description" in body) {
    const value = body["description"];
    if (typeof value !== "string" || value.trim().length === 0) {
      res.status(422).json({
        error: "`description` must be a non-empty string (whitespace only is rejected) when provided",
        code: "invalid_config"
      });
      return void 0;
    }
    if (Buffer.byteLength(value, "utf8") > MAX_DESCRIPTION_BYTES) {
      res.status(422).json({
        error: `\`description\` exceeds the ${MAX_DESCRIPTION_BYTES}-byte limit`,
        code: "invalid_config"
      });
      return void 0;
    }
    updates.description = value;
  }
  if ("systemPrompt" in body) {
    const value = body["systemPrompt"];
    if (typeof value !== "string" || value.trim().length === 0) {
      res.status(422).json({
        error: "`systemPrompt` must be a non-empty string (whitespace only is rejected) when provided",
        code: "invalid_config"
      });
      return void 0;
    }
    if (Buffer.byteLength(value, "utf8") > MAX_SYSTEM_PROMPT_BYTES) {
      res.status(422).json({
        error: `\`systemPrompt\` exceeds the ${MAX_SYSTEM_PROMPT_BYTES}-byte limit`,
        code: "invalid_config"
      });
      return void 0;
    }
    updates.systemPrompt = value;
  }
  if ("tools" in body) {
    const tools = parseStringArray(body["tools"], "tools", res);
    if (tools === null) return void 0;
    if (tools !== void 0) updates.tools = tools;
  }
  if ("disallowedTools" in body) {
    const disallowedTools = parseStringArray(
      body["disallowedTools"],
      "disallowedTools",
      res
    );
    if (disallowedTools === null) return void 0;
    if (disallowedTools !== void 0) {
      updates.disallowedTools = disallowedTools;
    }
  }
  if (rejectIfPresentWrongType(body, "model", "string", res)) return void 0;
  if (typeof body["model"] === "string") updates.model = body["model"];
  if (rejectIfPresentWrongType(body, "color", "string", res)) return void 0;
  if (typeof body["color"] === "string") updates.color = body["color"];
  if (rejectIfPresentWrongType(body, "approvalMode", "string", res)) {
    return void 0;
  }
  if (typeof body["approvalMode"] === "string") {
    if (!APPROVAL_MODES.includes(body["approvalMode"])) {
      res.status(422).json({
        error: `\`approvalMode\` must be one of ${JSON.stringify(APPROVAL_MODES)}`,
        code: "invalid_config"
      });
      return void 0;
    }
    updates.approvalMode = body["approvalMode"];
  }
  if (rejectIfPresentWrongType(body, "background", "boolean", res)) {
    return void 0;
  }
  if (typeof body["background"] === "boolean") {
    updates.background = body["background"];
  }
  if ("runConfig" in body) {
    const sanitized = sanitizeRunConfig(body["runConfig"], res);
    if (sanitized === null) return void 0;
    updates.runConfig = sanitized;
  }
  return updates;
}
__name(parseAgentUpdates, "parseAgentUpdates");
function parseStringArray(value, field, res) {
  if (value === void 0) return void 0;
  if (!Array.isArray(value) || value.some((v) => typeof v !== "string")) {
    res.status(422).json({
      error: `\`${field}\` must be an array of strings when provided`,
      code: "invalid_config"
    });
    return null;
  }
  if (value.length > MAX_TOOLS_ENTRIES) {
    res.status(422).json({
      error: `\`${field}\` exceeds the ${MAX_TOOLS_ENTRIES}-entry limit`,
      code: "invalid_config"
    });
    return null;
  }
  if (value.some((v) => v.length > MAX_TOOL_ID_LENGTH)) {
    res.status(422).json({
      error: `\`${field}\` entries must be at most ${MAX_TOOL_ID_LENGTH} characters`,
      code: "invalid_config"
    });
    return null;
  }
  return value;
}
__name(parseStringArray, "parseStringArray");
function rejectIfPresentWrongType(body, key, expected, res) {
  if (!(key in body)) return false;
  if (typeof body[key] === expected) return false;
  res.status(422).json({
    error: `\`${key}\` must be a ${expected} when provided`,
    code: "invalid_config"
  });
  return true;
}
__name(rejectIfPresentWrongType, "rejectIfPresentWrongType");
function isNoOpUpdate(existing, updates) {
  if (updates.description !== void 0 && updates.description !== existing.description) {
    return false;
  }
  if (updates.systemPrompt !== void 0 && updates.systemPrompt !== existing.systemPrompt) {
    return false;
  }
  if (updates.tools !== void 0 && !shallowArrayEqual(updates.tools, existing.tools)) {
    return false;
  }
  if (updates.disallowedTools !== void 0 && !shallowArrayEqual(updates.disallowedTools, existing.disallowedTools)) {
    return false;
  }
  if (updates.model !== void 0 && updates.model !== existing.model) {
    return false;
  }
  if (updates.color !== void 0 && updates.color !== existing.color) {
    return false;
  }
  if (updates.approvalMode !== void 0 && updates.approvalMode !== existing.approvalMode) {
    return false;
  }
  if (updates.background !== void 0 && updates.background !== existing.background) {
    return false;
  }
  if (updates.runConfig !== void 0) {
    const e = existing.runConfig ?? {};
    const u = updates.runConfig;
    if ("max_time_minutes" in u) {
      if (u["max_time_minutes"] !== e["max_time_minutes"]) return false;
    }
    if ("max_turns" in u) {
      if (u["max_turns"] !== e["max_turns"]) return false;
    }
  }
  return true;
}
__name(isNoOpUpdate, "isNoOpUpdate");
function shallowArrayEqual(a, b) {
  if (a === b) return true;
  if (!a || !b) return false;
  if (a.length !== b.length) return false;
  for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
  return true;
}
__name(shallowArrayEqual, "shallowArrayEqual");
function sanitizeRunConfig(raw, res) {
  if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
    res.status(422).json({
      error: "`runConfig` must be an object when provided",
      code: "invalid_config"
    });
    return null;
  }
  const input = raw;
  const out = {};
  if ("max_time_minutes" in input) {
    const v = input["max_time_minutes"];
    if (typeof v !== "number" || !Number.isFinite(v) || v <= 0) {
      res.status(422).json({
        error: "`runConfig.max_time_minutes` must be a positive finite number when provided",
        code: "invalid_config"
      });
      return null;
    }
    out["max_time_minutes"] = v;
  }
  if ("max_turns" in input) {
    const v = input["max_turns"];
    if (typeof v !== "number" || !Number.isFinite(v) || v <= 0 || !Number.isInteger(v)) {
      res.status(422).json({
        error: "`runConfig.max_turns` must be a positive integer when provided",
        code: "invalid_config"
      });
      return null;
    }
    out["max_turns"] = v;
  }
  return out;
}
__name(sanitizeRunConfig, "sanitizeRunConfig");
function toSummary(config) {
  const summary = {
    kind: "agent",
    name: config.name,
    description: config.description,
    level: config.level,
    isBuiltin: config.isBuiltin === true || config.level === "builtin",
    hasTools: Array.isArray(config.tools) && config.tools.length > 0
  };
  if (config.model) summary.model = config.model;
  if (config.color) summary.color = config.color;
  if (config.background !== void 0) summary.background = config.background;
  if (config.approvalMode) summary.approvalMode = config.approvalMode;
  if (config.extensionName) summary.extensionName = config.extensionName;
  if (config.filePath) summary.filePath = config.filePath;
  return summary;
}
__name(toSummary, "toSummary");
function toDetail(config) {
  const detail = {
    ...toSummary(config),
    systemPrompt: config.systemPrompt
  };
  if (config.tools) detail.tools = [...config.tools];
  if (config.disallowedTools) {
    detail.disallowedTools = [...config.disallowedTools];
  }
  if (config.runConfig) {
    const runConfig = {};
    if (typeof config.runConfig.max_time_minutes === "number") {
      runConfig.max_time_minutes = config.runConfig.max_time_minutes;
    }
    if (typeof config.runConfig.max_turns === "number") {
      runConfig.max_turns = config.runConfig.max_turns;
    }
    detail.runConfig = runConfig;
  }
  return detail;
}
__name(toDetail, "toDetail");
function createDaemonSubagentManager(boundWorkspace, safeMode = false) {
  const stub = {
    getSdkMode: /* @__PURE__ */ __name(() => false, "getSdkMode"),
    getProjectRoot: /* @__PURE__ */ __name(() => boundWorkspace, "getProjectRoot"),
    getActiveExtensions: /* @__PURE__ */ __name(() => [], "getActiveExtensions"),
    isSafeMode: /* @__PURE__ */ __name(() => safeMode, "isSafeMode"),
    getAgentsSettings: /* @__PURE__ */ __name(() => ({}), "getAgentsSettings")
  };
  const guarded = new Proxy(stub, {
    get(target, prop) {
      if (prop in target) {
        return target[prop];
      }
      if (prop === "then") return void 0;
      throw new Error(
        `qwen serve workspace agents: SubagentManager touched Config.${String(prop)} which the daemon stub does not implement. Add it to createDaemonSubagentManager and audit safety.`
      );
    },
    // Mirror the `get` trap. Without a `has` trap, a SubagentManager
    // path that does `if ('someMethod' in this.config)` would consult
    // `Reflect.has(target, prop)` directly and silently return false
    // for unimplemented methods — bypassing the throw the `get` trap
    // is supposed to surface. With the trap, an `in` check on an
    // unknown method throws the same way a property access would, so
    // both code paths behave consistently.
    has(target, prop) {
      if (prop in target) return true;
      if (prop === "then") return false;
      throw new Error(
        `qwen serve workspace agents: SubagentManager probed Config.${String(prop)} via 'in' check; the daemon stub does not implement it. Add it to createDaemonSubagentManager and audit safety.`
      );
    }
  });
  return new SubagentManager(guarded);
}
__name(createDaemonSubagentManager, "createDaemonSubagentManager");

// packages/cli/src/serve/session-organization-helpers.ts
init_esbuild_shims();
function createSessionOrganizationService(workspaceCwd) {
  return new SessionOrganizationService(workspaceCwd, (message) => {
    writeStderrLine(`qwen serve: session-org: ${message}`);
  });
}
__name(createSessionOrganizationService, "createSessionOrganizationService");

// packages/cli/src/serve/server/session-archive.ts
init_esbuild_shims();

// packages/cli/src/serve/scheduled-task-session-lifecycle.ts
init_esbuild_shims();
function isBoundTask(task) {
  return typeof task.sessionId === "string" && task.sessionId.length > 0;
}
__name(isBoundTask, "isBoundTask");
async function disableTasksForSessions(projectRoot, sessionIds) {
  if (sessionIds.length === 0) return;
  const targets = new Set(sessionIds);
  await updateCronTasks(projectRoot, (tasks) => {
    let changed = false;
    const next = tasks.map((task) => {
      if (isBoundTask(task) && targets.has(task.sessionId) && task.enabled !== false) {
        changed = true;
        return { ...task, enabled: false, disabledByArchive: true };
      }
      return task;
    });
    return changed ? next : tasks;
  });
}
__name(disableTasksForSessions, "disableTasksForSessions");
async function enableTasksForSessions(projectRoot, sessionIds, now = Date.now()) {
  if (sessionIds.length === 0) return;
  const targets = new Set(sessionIds);
  await updateCronTasks(projectRoot, (tasks) => {
    let changed = false;
    const next = tasks.map((task) => {
      if (isBoundTask(task) && targets.has(task.sessionId) && task.enabled === false && task.disabledByArchive === true) {
        changed = true;
        const resumed = { ...task, enabled: true };
        delete resumed.disabledByArchive;
        const minute = now - now % 6e4;
        if (resumed.recurring) {
          resumed.lastFiredAt = minute;
        } else {
          resumed.createdAt = now;
          resumed.lastFiredAt = minute;
        }
        return resumed;
      }
      return task;
    });
    return changed ? next : tasks;
  });
}
__name(enableTasksForSessions, "enableTasksForSessions");
async function removeTasksForSessions(projectRoot, sessionIds) {
  if (sessionIds.length === 0) return;
  const targets = new Set(sessionIds);
  await updateCronTasks(projectRoot, (tasks) => {
    const next = tasks.filter(
      (task) => !isBoundTask(task) || !targets.has(task.sessionId)
    );
    return next.length === tasks.length ? tasks : next;
  });
}
__name(removeTasksForSessions, "removeTasksForSessions");

// packages/cli/src/serve/server/session-archive.ts
var SessionArchiveCoordinator = class {
  static {
    __name(this, "SessionArchiveCoordinator");
  }
  exclusive = /* @__PURE__ */ new Set();
  shared = /* @__PURE__ */ new Map();
  assertNotTransitioning(sessionId) {
    if (this.exclusive.has(sessionId)) {
      throw new SessionArchivingError(sessionId);
    }
  }
  async runExclusiveMany(sessionIds, fn) {
    const uniqueSessionIds = [...new Set(sessionIds)];
    for (const sessionId of uniqueSessionIds) {
      this.assertNotTransitioning(sessionId);
      if ((this.shared.get(sessionId) ?? 0) > 0) {
        throw new SessionArchivingError(sessionId, "shared");
      }
    }
    for (const sessionId of uniqueSessionIds) {
      this.exclusive.add(sessionId);
    }
    try {
      return await fn();
    } finally {
      for (const sessionId of uniqueSessionIds) {
        this.exclusive.delete(sessionId);
      }
    }
  }
  async runSharedMany(sessionIds, fn) {
    const uniqueSessionIds = [...new Set(sessionIds)];
    for (const sessionId of uniqueSessionIds) {
      this.assertNotTransitioning(sessionId);
    }
    for (const sessionId of uniqueSessionIds) {
      this.shared.set(sessionId, (this.shared.get(sessionId) ?? 0) + 1);
    }
    try {
      return await fn();
    } finally {
      for (const sessionId of uniqueSessionIds) {
        const count = (this.shared.get(sessionId) ?? 1) - 1;
        if (count <= 0) {
          this.shared.delete(sessionId);
        } else {
          this.shared.set(sessionId, count);
        }
      }
    }
  }
};
async function deleteDaemonSessions(params) {
  const { sessionIds, service, bridge, coordinator, onError } = params;
  const uniqueSessionIds = [...new Set(sessionIds)];
  const closeErrors = [];
  const removed = [];
  const notFound = [];
  const removeErrors = [];
  for (const sessionId of uniqueSessionIds) {
    coordinator.assertNotTransitioning(sessionId);
  }
  await Promise.all(
    uniqueSessionIds.map(async (sessionId) => {
      try {
        await coordinator.runExclusiveMany([sessionId], async () => {
          let shouldRemove = false;
          try {
            await bridge.closeSession(sessionId);
            shouldRemove = true;
          } catch (closeErr) {
            if (closeErr instanceof SessionNotFoundError || closeErr instanceof Error && closeErr.name === "SessionNotFoundError") {
              shouldRemove = true;
            } else {
              const message = closeErr instanceof Error ? closeErr.message : String(closeErr);
              onError?.({ phase: "close", sessionId, error: message });
              closeErrors.push({ sessionId, error: message });
            }
          }
          if (!shouldRemove) return;
          try {
            if (await service.removeSession(sessionId)) {
              removed.push(sessionId);
            } else {
              notFound.push(sessionId);
            }
          } catch (removeErr) {
            const message = removeErr instanceof Error ? removeErr.message : String(removeErr);
            onError?.({ phase: "remove", sessionId, error: message });
            removeErrors.push({ sessionId, error: message });
          }
        });
      } catch (err) {
        if (err instanceof SessionArchivingError && err.lockKind === "exclusive") {
          throw err;
        }
        const message = err instanceof Error ? err.message : String(err);
        onError?.({ phase: "delete", sessionId, error: message });
        closeErrors.push({ sessionId, error: message });
      }
    })
  );
  await removeTasksForSessions(service.getProjectRoot(), removed).catch(
    (err) => {
      logSessionArchiveWarning(
        `removeTasksForSessions failed for [${removed.join(", ")}]: ${err instanceof Error ? err.message : String(err)}`
      );
    }
  );
  return { removed, notFound, errors: [...closeErrors, ...removeErrors] };
}
__name(deleteDaemonSessions, "deleteDaemonSessions");
async function assertSessionLoadable(workspaceCwd, sessionId) {
  const location = await new SessionService(workspaceCwd).getSessionLocation(
    sessionId
  );
  if (location === "archived") {
    throw new SessionArchivedError(sessionId);
  }
  if (location === "conflict") {
    throw new SessionConflictError(sessionId);
  }
  return location;
}
__name(assertSessionLoadable, "assertSessionLoadable");
async function assertSessionArchived(workspaceCwd, sessionId) {
  const location = await new SessionService(workspaceCwd).getSessionLocation(
    sessionId
  );
  if (location === "active") {
    throw new SessionNotArchivedError(sessionId);
  }
  if (location === "conflict") {
    throw new SessionConflictError(sessionId);
  }
  if (location === void 0) {
    throw new SessionNotFoundError(sessionId);
  }
}
__name(assertSessionArchived, "assertSessionArchived");
function isSessionNotFoundError(err) {
  return err instanceof SessionNotFoundError || err instanceof Error && err.name === "SessionNotFoundError";
}
__name(isSessionNotFoundError, "isSessionNotFoundError");
async function classifySessionLocations(service, sessionIds) {
  const result = {
    active: [],
    archived: [],
    notFound: [],
    errors: []
  };
  const locationResults = await Promise.allSettled(
    sessionIds.map(async (sessionId) => ({
      sessionId,
      location: await service.getSessionLocation(sessionId)
    }))
  );
  for (let i = 0; i < locationResults.length; i++) {
    const sessionId = sessionIds[i];
    const locationResult = locationResults[i];
    if (locationResult.status === "rejected") {
      result.errors.push({ sessionId, error: locationResult.reason });
      continue;
    }
    const location = locationResult.value.location;
    if (location === void 0) {
      result.notFound.push(sessionId);
    } else if (location === "archived") {
      result.archived.push(sessionId);
    } else if (location === "conflict") {
      result.errors.push({
        sessionId,
        error: new Error(`Session archive conflict: ${sessionId}`)
      });
    } else {
      result.active.push(sessionId);
    }
  }
  return result;
}
__name(classifySessionLocations, "classifySessionLocations");
function logSessionArchiveResult(action, result) {
  const changedLabel = action === "archive" ? "archived" : "unarchived";
  const alreadyLabel = action === "archive" ? "alreadyArchived" : "alreadyActive";
  const details = [
    `requested=${result.requested.length} requestedIds=${formatSessionIds(result.requested)}`,
    `${changedLabel}=${result.changed.length} ${changedLabel}Ids=${formatSessionIds(result.changed)}`,
    `${alreadyLabel}=${result.already.length} ${alreadyLabel}Ids=${formatSessionIds(result.already)}`,
    `notFound=${result.notFound.length} notFoundIds=${formatSessionIds(result.notFound)}`,
    `errors=${result.errors.length} errorIds=${formatSessionErrors(result.errors)}`
  ].join(" ");
  writeStderrLine(`qwen serve: sessions ${action} result ${details}`);
}
__name(logSessionArchiveResult, "logSessionArchiveResult");
function formatSessionIds(sessionIds) {
  return `[${sessionIds.map((sessionId) => safeLogValue(sessionId)).join(",")}]`;
}
__name(formatSessionIds, "formatSessionIds");
function formatSessionErrors(errors) {
  return `[${errors.map(
    ({ sessionId, error: error2 }) => `${safeLogValue(sessionId)}:${safeLogValue(errorMessage(error2))}`
  ).join(",")}]`;
}
__name(formatSessionErrors, "formatSessionErrors");
function errorMessage(error2) {
  return error2 instanceof Error ? error2.message : String(error2);
}
__name(errorMessage, "errorMessage");
function logSessionArchiveWarning(message) {
  writeStderrLine(`qwen serve: ${sanitizeLogLine(message)}`);
}
__name(logSessionArchiveWarning, "logSessionArchiveWarning");
var LOG_LINE_UNSAFE_RE = /[\x00-\x1f\x7f-\x9f\u200b-\u200f\u2028-\u202e\u2066-\u2069\ufeff]/g;
function sanitizeLogLine(message) {
  return message.replace(LOG_LINE_UNSAFE_RE, " ").slice(0, 4096);
}
__name(sanitizeLogLine, "sanitizeLogLine");
async function archiveDaemonSessions(params) {
  const { sessionIds, service, bridge, coordinator } = params;
  const uniqueSessionIds = [...new Set(sessionIds)];
  const archived = [];
  const alreadyArchived = [];
  const notFound = [];
  const errors = [];
  const initial = await classifySessionLocations(service, uniqueSessionIds);
  const activeIds = initial.active;
  alreadyArchived.push(...initial.archived);
  notFound.push(...initial.notFound);
  errors.push(...initial.errors);
  if (activeIds.length > 0) {
    await coordinator.runExclusiveMany(activeIds, async () => {
      const locked = await classifySessionLocations(service, activeIds);
      const closableIds = locked.active;
      alreadyArchived.push(...locked.archived);
      notFound.push(...locked.notFound);
      errors.push(...locked.errors);
      const closeResults = await Promise.allSettled(
        closableIds.map(async (sessionId) => {
          try {
            await bridge.closeSession(sessionId, void 0, {
              requireAgentClose: true
            });
          } catch (err) {
            if (!isSessionNotFoundError(err)) {
              throw err;
            }
          }
        })
      );
      const archiveIds = [];
      for (let i = 0; i < closeResults.length; i++) {
        const sessionId = closableIds[i];
        const result = closeResults[i];
        if (result.status === "fulfilled") {
          archiveIds.push(sessionId);
        } else {
          errors.push({ sessionId, error: result.reason });
        }
      }
      try {
        const archiveResult = await service.archiveSessions(archiveIds, {
          knownLocation: "active"
        });
        archived.push(...archiveResult.archived);
        alreadyArchived.push(...archiveResult.alreadyArchived);
        notFound.push(...archiveResult.notFound);
        errors.push(...archiveResult.errors);
      } catch (err) {
        for (const sessionId of archiveIds) {
          errors.push({ sessionId, error: err });
        }
      }
    });
  }
  logSessionArchiveResult("archive", {
    requested: uniqueSessionIds,
    changed: archived,
    already: alreadyArchived,
    notFound,
    errors
  });
  await disableTasksForSessions(service.getProjectRoot(), archived).catch(
    (err) => {
      logSessionArchiveWarning(
        `disableTasksForSessions failed for [${archived.join(", ")}]: ${err instanceof Error ? err.message : String(err)} \u2014 bound tasks may keep firing until reconciled`
      );
    }
  );
  return { archived, alreadyArchived, notFound, errors };
}
__name(archiveDaemonSessions, "archiveDaemonSessions");
async function unarchiveDaemonSessions(params) {
  const { sessionIds, service, coordinator } = params;
  const uniqueSessionIds = [...new Set(sessionIds)];
  const unarchived = [];
  const alreadyActive = [];
  const notFound = [];
  const errors = [];
  const initial = await classifySessionLocations(service, uniqueSessionIds);
  const archivedIds = initial.archived;
  alreadyActive.push(...initial.active);
  notFound.push(...initial.notFound);
  errors.push(...initial.errors);
  if (archivedIds.length > 0) {
    await coordinator.runExclusiveMany(archivedIds, async () => {
      const locked = await classifySessionLocations(service, archivedIds);
      const unarchiveIds = locked.archived;
      alreadyActive.push(...locked.active);
      notFound.push(...locked.notFound);
      errors.push(...locked.errors);
      if (unarchiveIds.length > 0) {
        try {
          const result = await service.unarchiveSessions(unarchiveIds, {
            knownLocation: "archived"
          });
          unarchived.push(...result.unarchived);
          alreadyActive.push(...result.alreadyActive);
          notFound.push(...result.notFound);
          errors.push(...result.errors);
        } catch (err) {
          for (const sessionId of unarchiveIds) {
            errors.push({ sessionId, error: err });
          }
        }
      }
    });
  }
  logSessionArchiveResult("unarchive", {
    requested: uniqueSessionIds,
    changed: unarchived,
    already: alreadyActive,
    notFound,
    errors
  });
  const resumeSessionIds = [.../* @__PURE__ */ new Set([...unarchived, ...alreadyActive])];
  try {
    await enableTasksForSessions(service.getProjectRoot(), resumeSessionIds);
  } catch (err) {
    logSessionArchiveWarning(
      `enableTasksForSessions failed for [${resumeSessionIds.join(", ")}]: ${err instanceof Error ? err.message : String(err)}`
    );
    for (const sessionId of resumeSessionIds) {
      errors.push({ sessionId, error: err });
    }
  }
  return { unarchived, alreadyActive, notFound, errors };
}
__name(unarchiveDaemonSessions, "unarchiveDaemonSessions");

// packages/cli/src/serve/acp-http/json-rpc.ts
init_esbuild_shims();
var QWEN_METHOD_NS = "_qwen/";
var QWEN_META_KEY = "qwen";
var RPC = {
  PARSE_ERROR: -32700,
  INVALID_REQUEST: -32600,
  METHOD_NOT_FOUND: -32601,
  INVALID_PARAMS: -32602,
  INTERNAL_ERROR: -32603
};
function isObject(v) {
  return typeof v === "object" && v !== null && !Array.isArray(v);
}
__name(isObject, "isObject");
function isRequest(m) {
  return isObject(m) && m["jsonrpc"] === "2.0" && typeof m["method"] === "string" && "id" in m && m["id"] !== null && (typeof m["id"] === "number" || typeof m["id"] === "string");
}
__name(isRequest, "isRequest");
function isNotification(m) {
  return isObject(m) && m["jsonrpc"] === "2.0" && typeof m["method"] === "string" && !("id" in m);
}
__name(isNotification, "isNotification");
function isResponse(m) {
  return isObject(m) && m["jsonrpc"] === "2.0" && !("method" in m) && "id" in m && // JSON-RPC 2.0 §5: EXACTLY one of result/error (XOR). Accepting both
  // would let a buggy client's approval (result + error) be misread as a
  // cancellation by the `'error' in msg` check downstream. A dual-field
  // message therefore fails isRequest/isNotification/isResponse →
  // `parseInbound` rejects it → the POST handler returns 400 (logged by the
  // malformed-request path in index.ts), so the client is told its vote was
  // not accepted (not a silent drop); it can retry with a valid response,
  // and teardown still releases the pending entry if it doesn't.
  "result" in m !== "error" in m;
}
__name(isResponse, "isResponse");
var LOG_SAFE_RE = new RegExp(
  String.raw`[\x00-\x1f\x7f-\x9f\u200b-\u200f\u2028-\u202e\u2066-\u2069\ufeff]`,
  "g"
);
function logSafe(s) {
  return s.replace(LOG_SAFE_RE, " ");
}
__name(logSafe, "logSafe");
function success(id, result) {
  return { jsonrpc: "2.0", id, result };
}
__name(success, "success");
function error(id, code, message, data) {
  return {
    jsonrpc: "2.0",
    id,
    error: { code, message, ...data !== void 0 ? { data } : {} }
  };
}
__name(error, "error");
function notification(method, params) {
  return { jsonrpc: "2.0", method, params };
}
__name(notification, "notification");
function request(id, method, params) {
  return { jsonrpc: "2.0", id, method, params };
}
__name(request, "request");
function parseInbound(raw) {
  if (Array.isArray(raw)) {
    return {
      ok: false,
      error: error(null, RPC.INVALID_REQUEST, "JSON-RPC batch not supported")
    };
  }
  if (isRequest(raw) || isNotification(raw) || isResponse(raw)) {
    return { ok: true, message: raw };
  }
  return {
    ok: false,
    error: error(null, RPC.INVALID_REQUEST, "Malformed JSON-RPC message")
  };
}
__name(parseInbound, "parseInbound");

// packages/cli/src/serve/acp-http/dispatch.ts
function errMsg(err) {
  return err instanceof Error ? err.message : String(err);
}
__name(errMsg, "errMsg");
var debugLogger2 = createDebugLogger("ACP_HTTP_DISPATCH");
var SESSION_SHELL_METHOD = `${QWEN_METHOD_NS}session/shell`;
var INVALID_PERMISSION_OUTCOME_ERROR = '`outcome` must be `{ outcome: "cancelled" }` or `{ outcome: "selected", optionId: string }`';
var ALL_QWEN_VENDOR_METHODS = [
  `${QWEN_METHOD_NS}session/heartbeat`,
  `${QWEN_METHOD_NS}session/context`,
  `${QWEN_METHOD_NS}session/supported_commands`,
  `${QWEN_METHOD_NS}session/update_metadata`,
  `${QWEN_METHOD_NS}session/update_organization`,
  `${QWEN_METHOD_NS}workspace/session_groups/list`,
  `${QWEN_METHOD_NS}workspace/session_groups/create`,
  `${QWEN_METHOD_NS}workspace/session_groups/update`,
  `${QWEN_METHOD_NS}workspace/session_groups/delete`,
  `${QWEN_METHOD_NS}workspace/mcp`,
  `${QWEN_METHOD_NS}workspace/skills`,
  `${QWEN_METHOD_NS}workspace/providers`,
  `${QWEN_METHOD_NS}workspace/env`,
  `${QWEN_METHOD_NS}workspace/preflight`,
  `${QWEN_METHOD_NS}workspace/init`,
  `${QWEN_METHOD_NS}workspace/trust`,
  `${QWEN_METHOD_NS}workspace/trust/request`,
  `${QWEN_METHOD_NS}workspace/permissions`,
  `${QWEN_METHOD_NS}workspace/permissions/set`,
  `${QWEN_METHOD_NS}workspace/voice`,
  `${QWEN_METHOD_NS}workspace/voice/set`,
  `${QWEN_METHOD_NS}workspace/setup-github`,
  `${QWEN_METHOD_NS}workspace/set_tool_enabled`,
  `${QWEN_METHOD_NS}workspace/restart_mcp_server`,
  // Wave 1: session extensions
  `${QWEN_METHOD_NS}session/recap`,
  `${QWEN_METHOD_NS}session/btw`,
  SESSION_SHELL_METHOD,
  `${QWEN_METHOD_NS}session/detach`,
  `${QWEN_METHOD_NS}session/context_usage`,
  `${QWEN_METHOD_NS}session/tasks`,
  `${QWEN_METHOD_NS}session/lsp`,
  `${QWEN_METHOD_NS}session/artifacts`,
  `${QWEN_METHOD_NS}session/artifacts/add`,
  `${QWEN_METHOD_NS}session/artifacts/remove`,
  // Wave 1: memory
  `${QWEN_METHOD_NS}workspace/memory`,
  `${QWEN_METHOD_NS}workspace/memory/write`,
  `${QWEN_METHOD_NS}workspace/memory/remember`,
  `${QWEN_METHOD_NS}workspace/memory/remember/get`,
  `${QWEN_METHOD_NS}workspace/memory/forget`,
  `${QWEN_METHOD_NS}workspace/memory/forget/get`,
  `${QWEN_METHOD_NS}workspace/memory/dream`,
  `${QWEN_METHOD_NS}workspace/memory/dream/get`,
  // Wave 1: files
  `${QWEN_METHOD_NS}file/read`,
  `${QWEN_METHOD_NS}file/read_bytes`,
  `${QWEN_METHOD_NS}file/stat`,
  `${QWEN_METHOD_NS}file/list`,
  `${QWEN_METHOD_NS}file/glob`,
  `${QWEN_METHOD_NS}file/write`,
  `${QWEN_METHOD_NS}file/edit`,
  // Wave 1: auth
  `${QWEN_METHOD_NS}workspace/auth/status`,
  `${QWEN_METHOD_NS}workspace/auth/device_flow/start`,
  `${QWEN_METHOD_NS}workspace/auth/device_flow/get`,
  `${QWEN_METHOD_NS}workspace/auth/device_flow/cancel`,
  // Wave 1: remaining workspace
  `${QWEN_METHOD_NS}workspace/tools`,
  `${QWEN_METHOD_NS}workspace/mcp/tools`,
  `${QWEN_METHOD_NS}workspace/mcp/resources`,
  `${QWEN_METHOD_NS}workspace/mcp/servers/add`,
  `${QWEN_METHOD_NS}workspace/mcp/servers/remove`,
  `${QWEN_METHOD_NS}sessions/delete`,
  `${QWEN_METHOD_NS}sessions/archive`,
  `${QWEN_METHOD_NS}sessions/unarchive`,
  // Wave 2: agents
  `${QWEN_METHOD_NS}workspace/agents/list`,
  `${QWEN_METHOD_NS}workspace/agents/get`,
  `${QWEN_METHOD_NS}workspace/agents/create`,
  `${QWEN_METHOD_NS}workspace/agents/update`,
  `${QWEN_METHOD_NS}workspace/agents/delete`
];
function advertisedQwenVendorMethods(sessionShellCommandEnabled) {
  return ALL_QWEN_VENDOR_METHODS.filter(
    (method) => sessionShellCommandEnabled || method !== SESSION_SHELL_METHOD
  );
}
__name(advertisedQwenVendorMethods, "advertisedQwenVendorMethods");
var CONN_ROUTED_METHODS = /* @__PURE__ */ new Set([
  "authenticate",
  "session/new",
  "session/load",
  "session/resume",
  "session/list",
  "session/close",
  "session/fork",
  "session/permission",
  ...ALL_QWEN_VENDOR_METHODS
]);
var MAX_NAME_LENGTH = 256;
var DEFAULT_FILE_GLOB_MAX_RESULTS = 5e3;
var MAX_FILE_GLOB_MAX_RESULTS = 5e4;
var MAX_FILE_LINE_LIMIT2 = 2e3;
var AcpParamError = class extends Error {
  static {
    __name(this, "AcpParamError");
  }
};
function parseOptionalPositiveInteger(value, fallback, max) {
  if (value === void 0) return fallback;
  if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 1 || value > max) {
    return null;
  }
  return value;
}
__name(parseOptionalPositiveInteger, "parseOptionalPositiveInteger");
function parseOptionalSafeIntegerInRange(value, min, max) {
  if (value === void 0) return void 0;
  if (typeof value !== "number" || !Number.isSafeInteger(value) || value < min || value > max) {
    return null;
  }
  return value;
}
__name(parseOptionalSafeIntegerInRange, "parseOptionalSafeIntegerInRange");
function parseOptionalWorkspaceCwd2(params, boundWorkspace) {
  if (!("cwd" in params) || params["cwd"] === void 0) return boundWorkspace;
  const cwd = params["cwd"];
  if (typeof cwd !== "string") {
    throw new AcpParamError(
      "`cwd` must be a string absolute path when provided"
    );
  }
  if (cwd.length > MAX_WORKSPACE_PATH_LENGTH) {
    throw new AcpParamError(
      `\`cwd\` exceeds the ${MAX_WORKSPACE_PATH_LENGTH}-character limit`
    );
  }
  if (!path9.isAbsolute(cwd)) {
    throw new AcpParamError("`cwd` must be an absolute path when provided");
  }
  return cwd;
}
__name(parseOptionalWorkspaceCwd2, "parseOptionalWorkspaceCwd");
function validatePrompt(params) {
  const prompt = params["prompt"];
  if (!Array.isArray(prompt) || prompt.length === 0) {
    throw new AcpParamError(
      "`prompt` is required and must be a non-empty array of content blocks"
    );
  }
  if (!prompt.every(
    (b) => typeof b === "object" && b !== null && !Array.isArray(b)
  )) {
    throw new AcpParamError("each `prompt` element must be an object");
  }
}
__name(validatePrompt, "validatePrompt");
function parsePermissionResponse(params) {
  const outcome = params["outcome"];
  if (!isObject(outcome)) {
    throw new AcpParamError(INVALID_PERMISSION_OUTCOME_ERROR);
  }
  if (outcome["outcome"] !== "cancelled") {
    if (outcome["outcome"] !== "selected" || typeof outcome["optionId"] !== "string" || outcome["optionId"].length === 0) {
      throw new AcpParamError(INVALID_PERMISSION_OUTCOME_ERROR);
    }
  }
  const cleanOutcome = outcome["outcome"] === "cancelled" ? { outcome: "cancelled" } : { outcome: "selected", optionId: outcome["optionId"] };
  const response = { outcome: cleanOutcome };
  const answers = params["answers"];
  if (answers !== void 0) {
    if (isObject(answers) && Object.values(answers).every((value) => typeof value === "string")) {
      response["answers"] = answers;
    } else {
      writeStderrLine(
        "qwen serve: /acp session/permission dropping invalid `answers` (expected an object map of string values)"
      );
    }
  }
  if (isObject(params["_meta"])) {
    response["_meta"] = params["_meta"];
  }
  return response;
}
__name(parsePermissionResponse, "parsePermissionResponse");
function pickSessionArtifactInput(params) {
  const {
    title,
    kind,
    storage,
    description,
    workspacePath,
    managedId,
    url,
    mimeType,
    sizeBytes,
    metadata,
    retention,
    clientRetained
  } = params;
  return {
    title,
    kind,
    storage,
    description,
    workspacePath,
    managedId,
    url,
    mimeType,
    sizeBytes,
    metadata,
    retention,
    clientRetained
  };
}
__name(pickSessionArtifactInput, "pickSessionArtifactInput");
function toRpcError(err) {
  if (err instanceof AcpParamError || err instanceof InvalidCursorError) {
    return { code: RPC.INVALID_PARAMS, message: err.message };
  }
  if (err instanceof SessionOrganizationError) {
    const isServerSide = err.code === "session_organization_store_unreadable";
    return {
      code: isServerSide ? RPC.INTERNAL_ERROR : RPC.INVALID_PARAMS,
      message: err.message,
      data: {
        errorKind: err.code,
        ...err.field ? { field: err.field } : {}
      }
    };
  }
  if (err instanceof SubagentError) {
    return { code: RPC.INVALID_PARAMS, message: err.message };
  }
  if (err instanceof FsError) {
    return {
      code: RPC.INVALID_PARAMS,
      message: err.message,
      data: { errorKind: err.kind, hint: err.hint }
    };
  }
  if (err instanceof WorkspaceMemoryFileTooLargeError) {
    return {
      code: RPC.INVALID_PARAMS,
      message: err.message,
      data: { errorKind: "memory_file_too_large" }
    };
  }
  if (err instanceof WorkspaceMemoryWriteTimeoutError) {
    return {
      code: RPC.INTERNAL_ERROR,
      message: err.message,
      data: { errorKind: "memory_write_timeout" }
    };
  }
  if (err instanceof WorkspaceVoiceError) {
    return {
      code: err.status >= 400 && err.status < 500 ? RPC.INVALID_PARAMS : RPC.INTERNAL_ERROR,
      message: err.message,
      data: { errorKind: err.code }
    };
  }
  if (err instanceof WorkspaceSettingsPartialPersistError) {
    return {
      code: RPC.INTERNAL_ERROR,
      message: err.message,
      data: {
        errorKind: "partial_persist_error",
        committedKeys: err.committedWrites.map((write) => write.key)
      }
    };
  }
  if (err instanceof TooManyActiveDeviceFlowsError) {
    return {
      code: RPC.INTERNAL_ERROR,
      message: err.message,
      data: { errorKind: "too_many_active_flows" }
    };
  }
  if (err instanceof UnsupportedDeviceFlowProviderError) {
    return {
      code: RPC.INVALID_PARAMS,
      message: err.message,
      data: { errorKind: "unsupported_provider" }
    };
  }
  if (err instanceof UpstreamDeviceFlowError) {
    return {
      code: RPC.INTERNAL_ERROR,
      message: err.message,
      data: { errorKind: "upstream_error" }
    };
  }
  if (err instanceof SessionShellDisabledError) {
    return {
      code: RPC.INVALID_PARAMS,
      message: errMsg(err),
      data: { errorKind: "session_shell_disabled" }
    };
  }
  if (err instanceof SessionShellClientRequiredError) {
    return {
      code: RPC.INVALID_PARAMS,
      message: errMsg(err),
      data: { errorKind: "client_id_required" }
    };
  }
  if (err instanceof SessionArtifactAuthorizationError) {
    return {
      code: RPC.INVALID_REQUEST,
      message: err.message,
      data: {
        errorKind: "artifact_forbidden",
        sessionId: err.sessionId,
        artifactId: err.artifactId
      }
    };
  }
  if (err instanceof SessionArtifactValidationError) {
    return {
      code: RPC.INVALID_PARAMS,
      message: err.message,
      data: {
        errorKind: "artifact_validation_failed",
        ...err.field ? { field: err.field } : {}
      }
    };
  }
  const name = err instanceof Error ? err.name : "";
  switch (name) {
    case "SessionArchivedError":
      return {
        code: RPC.INTERNAL_ERROR,
        message: errMsg(err),
        data: {
          errorKind: "session_archived",
          sessionId: err.sessionId
        }
      };
    case "SessionConflictError":
      return {
        code: RPC.INTERNAL_ERROR,
        message: errMsg(err),
        data: {
          errorKind: "session_conflict",
          sessionId: err.sessionId
        }
      };
    case "SessionArchivingError":
      return {
        code: RPC.INTERNAL_ERROR,
        message: errMsg(err),
        data: {
          errorKind: "session_archiving",
          sessionId: err.sessionId
        }
      };
    case "SessionNotFoundError":
    case "InvalidSessionScopeError":
    case "WorkspaceMismatchError":
    case "InvalidClientIdError":
      return { code: RPC.INVALID_PARAMS, message: errMsg(err) };
    case "SessionLimitExceededError":
      return {
        code: RPC.INTERNAL_ERROR,
        message: errMsg(err),
        data: {
          errorKind: "session_limit_exceeded",
          limit: err.limit,
          scope: "workspace",
          retryable: true
        }
      };
    case "TotalSessionLimitExceededError":
      return {
        code: RPC.INTERNAL_ERROR,
        message: errMsg(err),
        data: {
          errorKind: "session_limit_exceeded",
          limit: err.limit,
          scope: err.scope,
          retryable: true
        }
      };
    case "PromptQueueFullError": {
      const promptErr = err;
      return {
        code: RPC.INTERNAL_ERROR,
        message: errMsg(err),
        data: {
          errorKind: "prompt_queue_full",
          sessionId: promptErr.sessionId,
          limit: promptErr.limit,
          pendingCount: promptErr.pendingCount
        }
      };
    }
    default:
      return {
        code: RPC.INTERNAL_ERROR,
        message: "Internal error",
        data: { errorKind: "internal" }
      };
  }
}
__name(toRpcError, "toRpcError");
function rpcErrorFrame(id, err) {
  const { code, message, data } = toRpcError(err);
  return error(id, code, message, data);
}
__name(rpcErrorFrame, "rpcErrorFrame");
var ACP_PROTOCOL_VERSION = 1;
var AcpDispatcher = class {
  constructor(bridge, boundWorkspace, workspace, workspaceRememberLane, fsFactory, deviceFlowRegistry, sessionShellCommandEnabled = false, registry, archiveCoordinator = new SessionArchiveCoordinator()) {
    this.bridge = bridge;
    this.boundWorkspace = boundWorkspace;
    this.workspace = workspace;
    this.workspaceRememberLane = workspaceRememberLane;
    this.fsFactory = fsFactory;
    this.deviceFlowRegistry = deviceFlowRegistry;
    this.sessionShellCommandEnabled = sessionShellCommandEnabled;
    this.registry = registry;
    this.archiveCoordinator = archiveCoordinator;
    this.agentManager = createDaemonSubagentManager(boundWorkspace);
  }
  static {
    __name(this, "AcpDispatcher");
  }
  agentManager;
  killOrphanSession(sessionId, removePersistedSession = false) {
    void this.bridge.killSession(sessionId, { requireZeroAttaches: true }).then(async (killed) => {
      if (killed && removePersistedSession) {
        await new SessionService(this.boundWorkspace).removeSession(
          sessionId
        );
      }
    }).catch(
      (err) => writeStderrLine(
        `qwen serve: /acp orphan killSession(${logSafe(sessionId)}) failed: ${logSafe(errMsg(err))}`
      )
    );
  }
  /**
   * Build the `WorkspaceRequestContext` for workspace-scoped operations
   * routed through the workspace service. The ACP dispatch has no session
   * context, so `sessionId` is omitted.
   */
  wsCtx(conn, method) {
    return {
      originatorClientId: conn.clientId,
      route: `ACP ${method}`,
      workspaceCwd: this.boundWorkspace
    };
  }
  parseBoundWorkspaceParam(params) {
    const rawWorkspace = typeof params["workspaceCwd"] === "string" ? params["workspaceCwd"] : void 0;
    if (rawWorkspace === void 0) {
      return this.boundWorkspace;
    }
    const requestedWorkspace = canonicalizeWorkspace(
      parseOptionalWorkspaceCwd2({ cwd: rawWorkspace }, this.boundWorkspace)
    );
    if (requestedWorkspace !== this.boundWorkspace) {
      throw new WorkspaceMismatchError(this.boundWorkspace, requestedWorkspace);
    }
    return requestedWorkspace;
  }
  parseSessionIds(params) {
    const sessionIds = params["sessionIds"];
    if (!Array.isArray(sessionIds) || sessionIds.length === 0 || sessionIds.length > 100 || !sessionIds.every((s) => typeof s === "string")) {
      throw new AcpParamError(
        "`sessionIds` must be non-empty string array (max 100)"
      );
    }
    return [...new Set(sessionIds)];
  }
  serializeSessionErrors(errors) {
    return errors.map((e) => ({
      sessionId: e.sessionId,
      error: errMsg(e.error)
    }));
  }
  /**
   * Build the bridge context for a per-session call. Echoes the clientId the
   * bridge STAMPED at create/attach (the connection's own id is unregistered
   * and would be rejected) and threads `fromLoopback` so the `local-only`
   * permission policy can gate votes by transport — symmetric with the REST
   * surface's `detectFromLoopback(req)`.
   *
   * Throws when no stamped clientId is present: the only callers reach here
   * AFTER `requireOwned`, so the binding must exist and carry the bridge's
   * id. A missing id means an invariant broke (a `session/new`/`load` that
   * didn't record it) — fail loud rather than silently send an unregistered
   * id whose rejection surfaces asynchronously, far from the cause.
   */
  sessionCtx(conn, sessionId, fromLoopback) {
    const clientId = conn.sessions.get(sessionId)?.clientId;
    if (!clientId) {
      throw new Error(
        `no bridge-stamped clientId for session ${sessionId} (ownership invariant violated)`
      );
    }
    return { clientId, fromLoopback };
  }
  /**
   * The session's ACP-shaped config options (model/mode/…), read from the
   * child's own session state. Returned in `session/new` and as the result
   * of `session/set_config_option`. Best-effort — `undefined` on error.
   */
  async configOptionsFor(sessionId) {
    try {
      const ctx = await this.bridge.getSessionContextStatus(sessionId);
      const co = ctx?.state?.configOptions;
      return Array.isArray(co) ? co : void 0;
    } catch (err) {
      writeStderrLine(
        `qwen serve: /acp configOptionsFor(${logSafe(sessionId)}) failed: ${logSafe(errMsg(err))}`
      );
      return void 0;
    }
  }
  /**
   * Extract ACP-standard `SessionModelState` from configOptions.
   * ConfigOptions carry model info as `{ category: 'model', type: 'select',
   * currentValue, options }`. Maps to `{ currentModelId, availableModels }`.
   */
  extractModelState(configOptions) {
    if (!configOptions) return void 0;
    const modelOpt = configOptions.find(
      (o) => typeof o === "object" && o !== null && o["category"] === "model"
    );
    if (!modelOpt) return void 0;
    const currentModelId = String(modelOpt["currentValue"] ?? "");
    const options = Array.isArray(modelOpt["options"]) ? modelOpt["options"] : [];
    return {
      currentModelId,
      availableModels: options.map((opt) => {
        const o = opt;
        return { id: String(o["value"] ?? o["id"] ?? "") };
      })
    };
  }
  /**
   * Extract ACP-standard `SessionModeState` from configOptions.
   * ConfigOptions carry mode info as `{ category: 'mode', type: 'select',
   * currentValue, options }`. Maps to `{ currentModeId, availableModes }`.
   */
  extractModeState(configOptions) {
    if (!configOptions) return void 0;
    const modeOpt = configOptions.find(
      (o) => typeof o === "object" && o !== null && o["category"] === "mode"
    );
    if (!modeOpt) return void 0;
    const currentModeId = String(modeOpt["currentValue"] ?? "");
    const options = Array.isArray(modeOpt["options"]) ? modeOpt["options"] : [];
    return {
      currentModeId,
      availableModes: options.map((opt) => {
        const o = opt;
        return { id: String(o["value"] ?? o["id"] ?? "") };
      })
    };
  }
  /**
   * Cancel a permission request the client abandoned (closed its stream /
   * connection before voting), so the bridge isn't left blocked. Invoked
   * by the connection-registry teardown path.
   */
  cancelAbandonedPermission(req, clientId) {
    try {
      this.bridge.respondToSessionPermission(
        req.sessionId,
        req.bridgeRequestId,
        { outcome: { outcome: "cancelled" } },
        clientId !== void 0 ? { clientId } : void 0
      );
      return true;
    } catch (err) {
      const msg = errMsg(err);
      if (/not found|unknown session/i.test(msg)) return true;
      writeStderrLine(
        `qwen serve: /acp cancelAbandonedPermission(${logSafe(req.sessionId)}) failed: ${logSafe(msg)}`
      );
      return false;
    }
  }
  /**
   * Build the `initialize` result advertising standard + `_qwen` caps.
   * Negotiates the protocol version: we only implement stable V1, so we
   * clamp to `[1, ACP_PROTOCOL_VERSION]` — a client asking for 0/negative
   * (ACP marks V0 a pre-release fallback) or a future version gets `1`
   * rather than an echoed version we don't actually implement.
   */
  buildInitializeResult(connectionId, requestedVersion) {
    const requested = typeof requestedVersion === "number" && Number.isFinite(requestedVersion) ? requestedVersion : ACP_PROTOCOL_VERSION;
    const negotiated = Math.max(1, Math.min(requested, ACP_PROTOCOL_VERSION));
    return {
      protocolVersion: negotiated,
      agentCapabilities: {
        loadSession: true,
        // Mirror acpAgent.ts promptCapabilities: #resolvePrompt handles audio
        // blocks identically to image (both become inlineData Parts).
        promptCapabilities: {
          image: true,
          audio: true,
          embeddedContext: true
        },
        // Model + mode are exposed via the STANDARD `session/set_config_option`
        // (categories `model`/`mode`); advertise that here.
        configOptions: true,
        // Vendor extensions are advertised under `_meta` keyed by domain
        // (ACP convention, e.g. `_meta: { "zed.dev": … }`). Clients
        // feature-detect before calling `_qwen/…` methods.
        _meta: {
          [QWEN_META_KEY]: {
            connectionId,
            workspaceCwd: this.boundWorkspace,
            methods: advertisedQwenVendorMethods(
              this.sessionShellCommandEnabled
            )
          },
          imageCapability: IMAGE_CAPABILITY
        }
      }
    };
  }
  /**
   * Gate a per-session operation on connection ownership. Sends a JSON-RPC
   * error and returns false when this connection never created/attached
   * the session (prevents driving or eavesdropping on another
   * connection's session). `session/new|load|resume` are the
   * ownership-GRANTING ops and skip this.
   */
  requireOwned(conn, sessionId, id) {
    if (conn.ownsSession(sessionId)) return true;
    if (id === void 0) {
      writeStderrLine(
        `qwen serve: /acp notification for unowned session ${logSafe(sessionId)} (dropped)`
      );
      return false;
    }
    conn.sendConn(
      error(
        id,
        RPC.INVALID_PARAMS,
        `Session ${sessionId} is not owned by this connection`
      )
    );
    return false;
  }
  async withMutableOwned(conn, sessionId, id, fn) {
    if (!this.requireOwned(conn, sessionId, id)) return;
    await this.archiveCoordinator.runSharedMany([sessionId], async () => {
      await fn();
    });
  }
  findPendingClientRequest(conn, id) {
    const req = conn.pending.get(id);
    if (req) return { conn, id, req };
    return this.registry?.findPendingClientRequest(id);
  }
  dropResolvedPermission(conn, id) {
    conn.pending.delete(id);
  }
  /**
   * Drop ONLY the calling connection's own pending permission entry for
   * `requestId`, never a sibling co-owner's. Under the consensus policy a vote
   * (or an unexpected vote error) from connection B must not delete connection
   * A's still-needed entry, which would stall the quorum. A connection that
   * never streamed the request holds no entry, so this is a no-op for it.
   */
  dropOwnPendingPermission(conn, requestId) {
    for (const [pid, preq] of conn.pending) {
      if (preq.kind === "permission" && preq.bridgeRequestId === requestId) {
        conn.pending.delete(pid);
        return;
      }
    }
  }
  /**
   * Handle one inbound POST message. Returns nothing — every reply is
   * delivered asynchronously on a long-lived SSE stream per the RFD
   * (`POST` itself answers `202`). `initialize` is handled by the caller
   * (it mints the connection) and never reaches here.
   */
  async handle(conn, msg, sessionHeader, reqLoopback) {
    const loopback = reqLoopback ?? conn.fromLoopback;
    if (isResponse(msg)) {
      try {
        this.resolveClientResponse(conn, msg, loopback);
      } catch (err) {
        writeStderrLine(
          `qwen serve: /acp response handling error: ${logSafe(errMsg(err))}`
        );
      }
      return;
    }
    if (!isRequest(msg) && !isNotification(msg)) return;
    const method = msg.method;
    const params = isObject(msg.params) ? msg.params : {};
    const id = isRequest(msg) ? msg.id : void 0;
    if (sessionHeader && typeof params["sessionId"] === "string" && params["sessionId"] !== sessionHeader) {
      if (id !== void 0) {
        conn.sendConn(
          error(
            id,
            RPC.INVALID_PARAMS,
            "Acp-Session-Id header does not match params.sessionId"
          )
        );
      }
      return;
    }
    try {
      switch (method) {
        case "authenticate":
          this.replyConn(conn, id, {});
          return;
        case "session/new": {
          const cwd = parseOptionalWorkspaceCwd2(params, this.boundWorkspace);
          const source = parseSessionSource(
            params["sourceType"],
            params["sourceId"]
          );
          if ("error" in source) {
            if (id !== void 0) {
              conn.sendConn(error(id, RPC.INVALID_PARAMS, source.error));
            }
            return;
          }
          const session = await this.bridge.spawnOrAttach({
            workspaceCwd: cwd,
            clientId: conn.clientId,
            sessionScope: "thread",
            ...source
          });
          if (conn.destroyed) {
            this.killOrphanSession(session.sessionId, true);
            return;
          }
          conn.getOrCreateSession(session.sessionId).clientId = session.clientId;
          conn.ownSession(session.sessionId);
          const configOptions = await this.configOptionsFor(session.sessionId);
          if (conn.destroyed) {
            this.killOrphanSession(session.sessionId, true);
            return;
          }
          const models = this.extractModelState(configOptions);
          const modes = this.extractModeState(configOptions);
          this.replyConn(conn, id, {
            sessionId: session.sessionId,
            ...session.sourceType ? { sourceType: session.sourceType } : {},
            ...session.sourceId !== void 0 ? { sourceId: session.sourceId } : {},
            ...session.sourcePersisted !== void 0 ? { sourcePersisted: session.sourcePersisted } : {},
            ...configOptions ? { configOptions } : {},
            ...models ? { models } : {},
            ...modes ? { modes } : {}
          });
          return;
        }
        case "session/load":
        case "session/resume": {
          const sessionId = String(params["sessionId"] ?? "");
          if (!sessionId) {
            if (id !== void 0) {
              conn.sendConn(
                error(id, RPC.INVALID_PARAMS, "`sessionId` is required")
              );
            }
            return;
          }
          if (conn.closingSessions.has(sessionId)) {
            if (id !== void 0) {
              conn.sendConn(
                error(
                  id,
                  RPC.INTERNAL_ERROR,
                  `session ${sessionId} is being closed; retry`
                )
              );
            }
            return;
          }
          const cwd = parseOptionalWorkspaceCwd2(params, this.boundWorkspace);
          const restored = await this.archiveCoordinator.runSharedMany(
            [sessionId],
            async () => {
              await assertSessionLoadable(cwd, sessionId);
              const metadata = await new SessionService(
                cwd
              ).readCreationMetadata(sessionId);
              return method === "session/load" ? await this.bridge.loadSession({
                sessionId,
                workspaceCwd: cwd,
                clientId: conn.clientId,
                historyReplay: "response",
                ...metadata
              }) : await this.bridge.resumeSession({
                sessionId,
                workspaceCwd: cwd,
                clientId: conn.clientId,
                ...metadata
              });
            }
          );
          const closeRaced = conn.closingSessions.has(sessionId);
          if (conn.destroyed || closeRaced) {
            const cleanup = restored.attached ? this.bridge.detachClient(sessionId, restored.clientId) : this.bridge.killSession(sessionId, {
              requireZeroAttaches: true
            });
            void cleanup.catch(
              (err) => writeStderrLine(
                `qwen serve: /acp orphan ${restored.attached ? "detach" : "kill"}(${logSafe(sessionId)}) teardown-race: ${logSafe(errMsg(err))}`
              )
            );
            if (closeRaced && !conn.destroyed && id !== void 0) {
              conn.sendConn(
                error(
                  id,
                  RPC.INTERNAL_ERROR,
                  `session ${sessionId} was closed during load; retry`
                )
              );
            }
            return;
          }
          conn.getOrCreateSession(sessionId).clientId = restored.clientId;
          if (method === "session/load") {
            conn.markInitialReplayPending(sessionId);
          }
          conn.ownSession(sessionId);
          const loadConfigOptions = await this.configOptionsFor(sessionId);
          const loadModels = this.extractModelState(loadConfigOptions);
          const loadModes = this.extractModeState(loadConfigOptions);
          const loadState = restored.state ?? {};
          const loadMeta = isObject(loadState._meta) ? loadState._meta : void 0;
          const loadQwenMeta = isObject(loadMeta?.[QWEN_META_KEY]) ? loadMeta[QWEN_META_KEY] : void 0;
          const replayStatus = method === "session/load" && restored.partial === true ? {
            partial: true,
            ...typeof restored.replayError === "string" ? { replayError: restored.replayError } : {}
          } : void 0;
          this.replyConn(conn, id, {
            ...loadState,
            ...replayStatus ? {
              _meta: {
                ...loadMeta ?? {},
                [QWEN_META_KEY]: {
                  ...loadQwenMeta ?? {},
                  sessionLoadReplay: replayStatus
                }
              }
            } : {},
            ...loadConfigOptions ? { configOptions: loadConfigOptions } : {},
            ...loadModels ? { models: loadModels } : {},
            ...loadModes ? { modes: loadModes } : {}
          });
          return;
        }
        case "session/list": {
          const workspaceCwd = this.parseBoundWorkspaceParam(params);
          const cursor = typeof params["cursor"] === "string" ? params["cursor"] : void 0;
          const rawView = typeof params["view"] === "string" ? params["view"] : void 0;
          let view;
          if (rawView !== void 0) {
            if (rawView !== "organized") {
              throw new AcpParamError('`view` must be "organized"');
            }
            view = rawView;
          }
          const group = typeof params["group"] === "string" ? params["group"] : void 0;
          if (group !== void 0 && view !== "organized") {
            throw new AcpParamError(
              '`group` requires `view` to be "organized"'
            );
          }
          const meta = isObject(params["_meta"]) ? params["_meta"] : void 0;
          const metaSize = typeof meta?.["size"] === "number" ? meta["size"] : void 0;
          const rawArchiveState = typeof params["archiveState"] === "string" ? params["archiveState"] : typeof meta?.["archiveState"] === "string" ? meta["archiveState"] : void 0;
          let archiveState;
          if (rawArchiveState !== void 0) {
            if (rawArchiveState !== "active" && rawArchiveState !== "archived") {
              throw new AcpParamError(
                '`archiveState` must be "active" or "archived"'
              );
            }
            archiveState = rawArchiveState;
          }
          const parentSessionId = typeof params["parentSessionId"] === "string" ? params["parentSessionId"] : void 0;
          if (parentSessionId !== void 0) {
            if (parentSessionId.length === 0) {
              throw new AcpParamError(
                "`parentSessionId` must be a non-empty string"
              );
            }
            if (view === "organized") {
              throw new AcpParamError(
                '`parentSessionId` is not supported with `view` "organized"'
              );
            }
          }
          const parsedSource = parseSessionSource(
            params["sourceType"],
            params["sourceId"]
          );
          if ("error" in parsedSource) {
            throw new AcpParamError(parsedSource.error);
          }
          const result = await listWorkspaceSessionsForResponse(
            this.bridge,
            workspaceCwd,
            {
              cursor,
              size: metaSize,
              archiveState,
              view,
              group,
              parentSessionId,
              ...parsedSource
            }
          );
          this.replyConn(conn, id, {
            sessions: result.sessions.map((s) => ({
              sessionId: s.sessionId,
              workspaceCwd: s.workspaceCwd,
              cwd: s.workspaceCwd,
              createdAt: s.createdAt,
              updatedAt: s.updatedAt,
              displayName: s.displayName,
              title: s.displayName,
              ...s.parentSessionId !== void 0 ? { parentSessionId: s.parentSessionId } : {},
              ...s.sourceType !== void 0 ? { sourceType: s.sourceType } : {},
              ...s.sourceId !== void 0 ? { sourceId: s.sourceId } : {},
              clientCount: s.clientCount,
              hasActivePrompt: s.hasActivePrompt,
              isArchived: s.isArchived === true,
              ...s.isPinned !== void 0 ? { isPinned: s.isPinned } : {},
              ...s.pinnedAt !== void 0 ? { pinnedAt: s.pinnedAt } : {},
              ...s.groupId !== void 0 ? { groupId: s.groupId } : {},
              ...s.color !== void 0 ? { color: s.color } : {}
            })),
            ...result.nextCursor != null ? { nextCursor: result.nextCursor } : {},
            ...result.liveMergeFailed ? { liveMergeFailed: true } : {},
            ...result.truncated ? { truncated: true } : {}
          });
          return;
        }
        case "session/close": {
          const sessionId = String(params["sessionId"] ?? "");
          if (!this.requireOwned(conn, sessionId, id)) return;
          conn.ownedSessions.delete(sessionId);
          conn.closingSessions.add(sessionId);
          let closeStarted = false;
          const closeSession = /* @__PURE__ */ __name(async () => {
            closeStarted = true;
            try {
              await this.bridge.closeSession(
                sessionId,
                this.sessionCtx(conn, sessionId, loopback)
              );
            } finally {
              try {
                conn.closeSessionStream(sessionId);
              } catch (teardownErr) {
                writeStderrLine(
                  `qwen serve: /acp session/close local teardown failed (${logSafe(sessionId)}): ${logSafe(errMsg(teardownErr))}`
                );
              }
            }
          }, "closeSession");
          try {
            try {
              await this.archiveCoordinator.runExclusiveMany(
                [sessionId],
                closeSession
              );
            } catch (err) {
              const promptAbort = conn.sessions.get(sessionId)?.promptAbort;
              if (err instanceof SessionArchivingError && err.lockKind === "shared" && promptAbort !== void 0) {
                await this.archiveCoordinator.runSharedMany(
                  [sessionId],
                  closeSession
                );
              } else {
                throw err;
              }
            }
          } catch (err) {
            if (!closeStarted) {
              conn.ownedSessions.add(sessionId);
            }
            throw err;
          } finally {
            conn.closingSessions.delete(sessionId);
          }
          this.replyConn(conn, id, {});
          return;
        }
        // ACP standard: session/fork — create a branched copy of an existing
        // session. Maps to bridge.branchSession().
        case "session/fork": {
          const sessionId = String(params["sessionId"] ?? "");
          if (!sessionId) {
            if (id !== void 0) {
              conn.sendConn(
                error(id, RPC.INVALID_PARAMS, "`sessionId` is required")
              );
            }
            return;
          }
          await this.withMutableOwned(conn, sessionId, id, async () => {
            const ctx = this.sessionCtx(conn, sessionId, loopback);
            const result = await this.bridge.branchSession(
              sessionId,
              {
                name: typeof params["name"] === "string" ? params["name"] : void 0
              },
              ctx
            );
            if (conn.destroyed) {
              this.killOrphanSession(result.sessionId);
              return;
            }
            conn.getOrCreateSession(result.sessionId).clientId = result.clientId;
            conn.ownSession(result.sessionId);
            const configOptions = await this.configOptionsFor(result.sessionId);
            const models = this.extractModelState(configOptions);
            const modes = this.extractModeState(configOptions);
            this.replyConn(conn, id, {
              sessionId: result.sessionId,
              ...configOptions ? { configOptions } : {},
              ...models ? { models } : {},
              ...modes ? { modes } : {}
            });
          });
          return;
        }
        case "session/cancel": {
          const sessionId = String(params["sessionId"] ?? "");
          await this.withMutableOwned(conn, sessionId, id, async () => {
            conn.sessions.get(sessionId)?.promptAbort?.abort();
            await this.bridge.cancelSession(
              sessionId,
              // Forward client-supplied cancel fields (reason/context) while
              // force-stamping sessionId — mirrors the REST surface.
              { ...params, sessionId },
              this.sessionCtx(conn, sessionId, loopback)
            );
            if (id !== void 0) this.replySession(conn, sessionId, id, {});
          });
          return;
        }
        case "session/prompt": {
          const sessionId = String(params["sessionId"] ?? "");
          await this.withMutableOwned(conn, sessionId, id, async () => {
            validatePrompt(params);
            await this.handlePrompt(conn, sessionId, id, params, loopback);
          });
          return;
        }
        case "session/permission": {
          const requestId = typeof params["requestId"] === "string" ? params["requestId"] : "";
          if (!requestId) {
            writeStderrLine(
              `qwen serve: /acp session/permission rejected: \`requestId\` is required`
            );
            if (id !== void 0) {
              conn.sendConn(
                error(id, RPC.INVALID_PARAMS, "`requestId` is required", {
                  httpStatus: 400,
                  requestId
                })
              );
            }
            return;
          }
          let response;
          try {
            response = parsePermissionResponse(params);
          } catch (err) {
            if (err instanceof AcpParamError) {
              writeStderrLine(
                `qwen serve: /acp session/permission invalid params (requestId ${logSafe(requestId)}): ${logSafe(err.message)}`
              );
              if (id !== void 0) {
                conn.sendConn(
                  error(id, RPC.INVALID_PARAMS, err.message, {
                    httpStatus: 400,
                    requestId
                  })
                );
              }
              return;
            }
            throw err;
          }
          const sessionIdParam = typeof params["sessionId"] === "string" && params["sessionId"].length > 0 ? params["sessionId"] : void 0;
          const pendingRef = this.registry?.findPendingPermission(requestId);
          if (sessionIdParam && pendingRef && sessionIdParam !== pendingRef.req.sessionId) {
            writeStderrLine(
              `qwen serve: /acp session/permission vote rejected: requestId ${logSafe(requestId)} does not belong to session ${logSafe(sessionIdParam)}`
            );
            if (id !== void 0) {
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  "requestId does not belong to the specified session",
                  { httpStatus: 409, sessionId: sessionIdParam, requestId }
                )
              );
            }
            return;
          }
          if (this.registry && !pendingRef) {
            writeStderrLine(
              `qwen serve: /acp session/permission vote dropped: no pending request for requestId ${logSafe(requestId)}`
            );
            if (id !== void 0) {
              conn.sendConn(
                error(id, RPC.INVALID_PARAMS, "No pending permission request", {
                  httpStatus: 404,
                  requestId
                })
              );
            }
            return;
          }
          const sessionId = pendingRef?.req.sessionId ?? sessionIdParam;
          if (!sessionId) {
            writeStderrLine(
              `qwen serve: /acp session/permission vote dropped: no pending request for requestId ${logSafe(requestId)}`
            );
            if (id !== void 0) {
              conn.sendConn(
                error(id, RPC.INVALID_PARAMS, "No pending permission request", {
                  httpStatus: 404,
                  requestId
                })
              );
            }
            return;
          }
          if (!conn.ownsSession(sessionId)) {
            writeStderrLine(
              `qwen serve: /acp session/permission vote rejected: session ${logSafe(sessionId)} not owned by this connection (requestId ${logSafe(requestId)})`
            );
            if (id !== void 0) {
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  "Session not owned by this connection",
                  { httpStatus: 403, sessionId, requestId }
                )
              );
            }
            return;
          }
          let accepted;
          try {
            accepted = this.bridge.respondToSessionPermission(
              sessionId,
              requestId,
              response,
              this.sessionCtx(conn, sessionId, loopback)
            );
          } catch (err) {
            if (err instanceof InvalidPermissionOptionError) {
              writeStderrLine(
                `qwen serve: /acp session/permission invalid option (${logSafe(sessionId)}, requestId ${logSafe(requestId)}): ${logSafe(err.message)}`
              );
              if (id !== void 0) {
                conn.sendConn(
                  error(id, RPC.INVALID_PARAMS, err.message, {
                    httpStatus: 400,
                    code: "invalid_option_id",
                    requestId: err.requestId,
                    optionId: err.optionId
                  })
                );
              }
              return;
            }
            if (err instanceof PermissionForbiddenError) {
              writeStderrLine(
                `qwen serve: /acp session/permission forbidden (${logSafe(sessionId)}, requestId ${logSafe(requestId)}): ${logSafe(err.message)}`
              );
              if (id !== void 0) {
                conn.sendConn(
                  error(id, RPC.INVALID_PARAMS, err.message, {
                    httpStatus: 403,
                    code: "permission_forbidden",
                    requestId: err.requestId,
                    sessionId: err.sessionId,
                    reason: err.reason
                  })
                );
              }
              return;
            }
            if (err instanceof PermissionPolicyNotImplementedError) {
              writeStderrLine(
                `qwen serve: /acp session/permission policy not implemented (${logSafe(sessionId)}, requestId ${logSafe(requestId)}): ${logSafe(err.message)}`
              );
              if (id !== void 0) {
                conn.sendConn(
                  error(id, RPC.INTERNAL_ERROR, err.message, {
                    httpStatus: 501,
                    code: "permission_policy_not_implemented",
                    policy: err.policy
                  })
                );
              }
              return;
            }
            if (err instanceof CancelSentinelCollisionError) {
              writeStderrLine(
                `qwen serve: /acp session/permission cancel-sentinel collision (${logSafe(sessionId)}, requestId ${logSafe(requestId)}): ${logSafe(err.message)}`
              );
              if (id !== void 0) {
                conn.sendConn(
                  error(id, RPC.INTERNAL_ERROR, err.message, {
                    httpStatus: 500,
                    code: "cancel_sentinel_collision",
                    requestId: err.requestId,
                    sentinel: err.sentinel
                  })
                );
              }
              return;
            }
            writeStderrLine(
              `qwen serve: /acp session/permission vote failed (${logSafe(sessionId)}, requestId ${logSafe(requestId)}): ${logSafe(errMsg(err))}`
            );
            const cancelled = this.cancelAbandonedPermission(
              { sessionId, bridgeRequestId: requestId },
              pendingRef?.conn.sessions.get(sessionId)?.clientId
            );
            if (cancelled) {
              this.dropOwnPendingPermission(conn, requestId);
            }
            throw err;
          }
          if (!accepted) {
            writeStderrLine(
              `qwen serve: /acp session/permission vote not accepted by bridge (${logSafe(sessionId)}, requestId ${logSafe(requestId)})`
            );
            if (id !== void 0) {
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  "Permission vote not accepted (request already resolved)",
                  {
                    httpStatus: 409,
                    sessionId,
                    requestId
                  }
                )
              );
            }
            return;
          }
          this.dropOwnPendingPermission(conn, requestId);
          writeStderrLine(
            `qwen serve: /acp session/permission vote accepted (${logSafe(sessionId)}, requestId ${logSafe(requestId)}, connection ${logSafe(conn.connectionId.slice(0, 8))})`
          );
          this.replyConn(conn, id, {});
          return;
        }
        // STANDARD method (SDK 0.14.1, non-`unstable_`): model + mode live
        // here under categories `model`/`mode`, routed to the existing bridge
        // setters. Replaces the old vendor `_qwen/session/set_model`.
        case "session/set_config_option": {
          const sessionId = String(params["sessionId"] ?? "");
          await this.withMutableOwned(conn, sessionId, id, async () => {
            const configId = String(params["configId"] ?? "");
            const rawValue = params["value"];
            const ctx = this.sessionCtx(conn, sessionId, loopback);
            if (typeof rawValue !== "string" || rawValue.length === 0) {
              if (id !== void 0) {
                this.replySession(
                  conn,
                  sessionId,
                  id,
                  void 0,
                  error(
                    id,
                    RPC.INVALID_PARAMS,
                    "`value` must be a non-empty string"
                  )
                );
              }
              return;
            }
            if (configId === "model") {
              await this.bridge.setSessionModel(
                sessionId,
                { modelId: rawValue },
                ctx
              );
            } else if (configId === "mode") {
              if (!APPROVAL_MODES.includes(rawValue)) {
                if (id !== void 0) {
                  this.replySession(
                    conn,
                    sessionId,
                    id,
                    void 0,
                    error(
                      id,
                      RPC.INVALID_PARAMS,
                      `invalid mode "${rawValue}" (expected one of: ${APPROVAL_MODES.join(", ")})`
                    )
                  );
                }
                return;
              }
              await this.bridge.setSessionApprovalMode(
                sessionId,
                rawValue,
                { persist: params["persist"] === true },
                ctx
              );
            } else {
              if (id !== void 0) {
                this.replySession(
                  conn,
                  sessionId,
                  id,
                  void 0,
                  error(
                    id,
                    RPC.INVALID_PARAMS,
                    `Unknown configId: ${configId}`
                  )
                );
              }
              return;
            }
            const configOptions = await this.configOptionsFor(sessionId);
            this.replySession(conn, sessionId, id, { configOptions });
          });
          return;
        }
        // ACP standard: session/set_mode — dedicated method for mode changes.
        // Maps to the same bridge call as set_config_option with configId='mode'.
        case "session/set_mode": {
          const sessionId = String(params["sessionId"] ?? "");
          if (!sessionId) {
            if (id !== void 0)
              conn.sendConn(
                error(id, RPC.INVALID_PARAMS, "`sessionId` is required")
              );
            return;
          }
          await this.withMutableOwned(conn, sessionId, id, async () => {
            const modeId = String(params["modeId"] ?? "");
            if (!modeId || !APPROVAL_MODES.includes(modeId)) {
              if (id !== void 0) {
                this.replySession(
                  conn,
                  sessionId,
                  id,
                  void 0,
                  error(
                    id,
                    RPC.INVALID_PARAMS,
                    `invalid modeId "${modeId}" (expected one of: ${APPROVAL_MODES.join(", ")})`
                  )
                );
              }
              return;
            }
            const ctx = this.sessionCtx(conn, sessionId, loopback);
            await this.bridge.setSessionApprovalMode(
              sessionId,
              modeId,
              { persist: false },
              ctx
            );
            this.replySession(conn, sessionId, id, {});
          });
          return;
        }
        // ACP standard (unstable): session/set_model — dedicated method for
        // model changes. Maps to the same bridge call as set_config_option
        // with configId='model'.
        case "session/set_model": {
          const sessionId = String(params["sessionId"] ?? "");
          if (!sessionId) {
            if (id !== void 0)
              conn.sendConn(
                error(id, RPC.INVALID_PARAMS, "`sessionId` is required")
              );
            return;
          }
          await this.withMutableOwned(conn, sessionId, id, async () => {
            const modelId = String(params["modelId"] ?? "");
            if (!modelId) {
              if (id !== void 0) {
                this.replySession(
                  conn,
                  sessionId,
                  id,
                  void 0,
                  error(id, RPC.INVALID_PARAMS, "`modelId` is required")
                );
              }
              return;
            }
            const ctx = this.sessionCtx(conn, sessionId, loopback);
            await this.bridge.setSessionModel(
              sessionId,
              { modelId, sessionId },
              ctx
            );
            this.replySession(conn, sessionId, id, {});
          });
          return;
        }
        case `${QWEN_METHOD_NS}session/heartbeat`: {
          const sessionId = String(params["sessionId"] ?? "");
          if (!this.requireOwned(conn, sessionId, id)) return;
          const result = this.bridge.recordHeartbeat(
            sessionId,
            this.sessionCtx(conn, sessionId, loopback)
          );
          this.replyConn(conn, id, result);
          return;
        }
        case `${QWEN_METHOD_NS}session/context`: {
          const sessionId = String(params["sessionId"] ?? "");
          if (!this.requireOwned(conn, sessionId, id)) return;
          this.replyConn(
            conn,
            id,
            await this.bridge.getSessionContextStatus(sessionId)
          );
          return;
        }
        case `${QWEN_METHOD_NS}session/supported_commands`: {
          const sessionId = String(params["sessionId"] ?? "");
          if (!this.requireOwned(conn, sessionId, id)) return;
          this.replyConn(
            conn,
            id,
            await this.bridge.getSessionSupportedCommandsStatus(sessionId)
          );
          return;
        }
        case `${QWEN_METHOD_NS}session/update_metadata`: {
          const sessionId = String(params["sessionId"] ?? "");
          await this.withMutableOwned(conn, sessionId, id, async () => {
            const metadata = isObject(params["metadata"]) ? params["metadata"] : {};
            const result = this.bridge.updateSessionMetadata(
              sessionId,
              metadata,
              this.sessionCtx(conn, sessionId, loopback)
            );
            this.replyConn(conn, id, result);
          });
          return;
        }
        case `${QWEN_METHOD_NS}session/update_organization`: {
          const sessionId = String(params["sessionId"] ?? "");
          if (!sessionId) {
            throw new AcpParamError("`sessionId` is required");
          }
          if ("isPinned" in params && typeof params["isPinned"] !== "boolean") {
            throw new AcpParamError("`isPinned` must be a boolean");
          }
          if ("groupId" in params && params["groupId"] !== null && typeof params["groupId"] !== "string") {
            throw new AcpParamError("`groupId` must be a string or null");
          }
          if ("color" in params && params["color"] !== null && (typeof params["color"] !== "string" || !GROUP_COLOR_OPTIONS.includes(
            params["color"]
          ))) {
            throw new AcpParamError(
              "`color` must be a supported color or null"
            );
          }
          await this.archiveCoordinator.runSharedMany([sessionId], async () => {
            const sessionService = new SessionService(this.boundWorkspace);
            let exists = await sessionService.sessionExistsInAnyState(sessionId);
            if (!exists) {
              try {
                const liveSummary = this.bridge.getSessionSummary(sessionId);
                exists = liveSummary.workspaceCwd === this.boundWorkspace;
              } catch {
                exists = false;
              }
            }
            if (!exists) {
              throw new AcpParamError(`Session not found: ${sessionId}`);
            }
            const organization = await createSessionOrganizationService(
              this.boundWorkspace
            ).updateSessionOrganization(sessionId, {
              ...typeof params["isPinned"] === "boolean" ? { isPinned: params["isPinned"] } : {},
              ..."groupId" in params ? { groupId: params["groupId"] } : {},
              ..."color" in params ? { color: params["color"] } : {}
            });
            this.replyConn(conn, id, { sessionId, ...organization });
          });
          return;
        }
        case `${QWEN_METHOD_NS}workspace/session_groups/list`: {
          const workspaceCwd = this.parseBoundWorkspaceParam(params);
          const groups = await createSessionOrganizationService(workspaceCwd).listGroups();
          this.replyConn(conn, id, groups);
          return;
        }
        case `${QWEN_METHOD_NS}workspace/session_groups/create`: {
          const workspaceCwd = this.parseBoundWorkspaceParam(params);
          const group = await createSessionOrganizationService(
            workspaceCwd
          ).createGroup({
            name: params["name"],
            color: params["color"]
          });
          this.replyConn(conn, id, { group });
          return;
        }
        case `${QWEN_METHOD_NS}workspace/session_groups/update`: {
          const workspaceCwd = this.parseBoundWorkspaceParam(params);
          const groupId = String(params["groupId"] ?? "");
          if (!groupId) {
            throw new AcpParamError("`groupId` is required");
          }
          const group = await createSessionOrganizationService(
            workspaceCwd
          ).updateGroup(groupId, {
            ..."name" in params ? { name: params["name"] } : {},
            ..."color" in params ? { color: params["color"] } : {},
            ..."order" in params ? { order: params["order"] } : {}
          });
          this.replyConn(conn, id, { group });
          return;
        }
        case `${QWEN_METHOD_NS}workspace/session_groups/delete`: {
          const workspaceCwd = this.parseBoundWorkspaceParam(params);
          const groupId = String(params["groupId"] ?? "");
          if (!groupId) {
            throw new AcpParamError("`groupId` is required");
          }
          const deleted = await createSessionOrganizationService(workspaceCwd).deleteGroup(
            groupId
          );
          this.replyConn(conn, id, { deleted });
          return;
        }
        case `${QWEN_METHOD_NS}workspace/mcp`:
          this.replyConn(
            conn,
            id,
            await this.workspace.getWorkspaceMcpStatus(
              this.wsCtx(conn, method)
            )
          );
          return;
        case `${QWEN_METHOD_NS}workspace/skills`:
          this.replyConn(
            conn,
            id,
            await this.workspace.getWorkspaceSkillsStatus(
              this.wsCtx(conn, method)
            )
          );
          return;
        case `${QWEN_METHOD_NS}workspace/providers`:
          this.replyConn(
            conn,
            id,
            await this.workspace.getWorkspaceProvidersStatus(
              this.wsCtx(conn, method)
            )
          );
          return;
        case `${QWEN_METHOD_NS}workspace/env`:
          this.replyConn(
            conn,
            id,
            await this.workspace.getWorkspaceEnvStatus(
              this.wsCtx(conn, method)
            )
          );
          return;
        case `${QWEN_METHOD_NS}workspace/preflight`:
          this.replyConn(
            conn,
            id,
            await this.workspace.getWorkspacePreflightStatus(
              this.wsCtx(conn, method)
            )
          );
          return;
        case `${QWEN_METHOD_NS}workspace/init`: {
          const rawForce = params["force"];
          if (rawForce !== void 0 && typeof rawForce !== "boolean") {
            if (id !== void 0) {
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  "`force` must be a boolean when provided"
                )
              );
            }
            return;
          }
          const force = rawForce === true;
          const result = await this.workspace.initWorkspace(
            this.wsCtx(conn, method),
            { force }
          );
          this.replyConn(conn, id, result);
          return;
        }
        case `${QWEN_METHOD_NS}workspace/trust`: {
          const result = await this.workspace.getWorkspaceTrustStatus(
            this.wsCtx(conn, method)
          );
          this.replyConn(conn, id, result);
          return;
        }
        case `${QWEN_METHOD_NS}workspace/trust/request`: {
          const desiredState = params["desiredState"];
          if (desiredState !== "trusted" && desiredState !== "untrusted") {
            if (id !== void 0) {
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  '`desiredState` must be "trusted" or "untrusted"'
                )
              );
            }
            return;
          }
          const reason = params["reason"];
          if (reason !== void 0 && (typeof reason !== "string" || reason.length > MAX_TRUST_REASON_LENGTH)) {
            if (id !== void 0) {
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  `\`reason\` must be a string up to ${MAX_TRUST_REASON_LENGTH} chars`
                )
              );
            }
            return;
          }
          const ctx = this.wsCtx(conn, method);
          const status = await this.workspace.getWorkspaceTrustStatus(ctx);
          if (!status.folderTrustEnabled) {
            if (id !== void 0) {
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_REQUEST,
                  "Folder trust is disabled for this workspace"
                )
              );
            }
            return;
          }
          const result = await this.workspace.requestWorkspaceTrustChange(ctx, {
            desiredState,
            ...reason !== void 0 ? { reason } : {}
          });
          this.replyConn(conn, id, result);
          return;
        }
        case `${QWEN_METHOD_NS}workspace/permissions`: {
          const result = await this.workspace.getWorkspacePermissionsStatus(
            this.wsCtx(conn, method)
          );
          this.replyConn(conn, id, result);
          return;
        }
        case `${QWEN_METHOD_NS}workspace/permissions/set`: {
          const scope = params["scope"];
          if (scope !== "user" && scope !== "workspace") {
            if (id !== void 0) {
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  '`scope` must be "user" or "workspace"'
                )
              );
            }
            return;
          }
          const ruleType = params["ruleType"];
          if (!isPermissionRuleType(ruleType)) {
            if (id !== void 0) {
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  '`ruleType` must be "allow", "ask", or "deny"'
                )
              );
            }
            return;
          }
          let rules;
          try {
            const settings = loadSettings(this.boundWorkspace);
            const scopeSettings = scope === "workspace" ? settings.workspace.settings : settings.user.settings;
            const existingRules = readPermissionRuleSet(scopeSettings)[ruleType];
            rules = normalizePermissionRules(params["rules"], {
              existingRules
            });
          } catch (err) {
            if (err instanceof PermissionRulesValidationError) {
              if (id !== void 0) {
                conn.sendConn(error(id, RPC.INVALID_PARAMS, err.message));
              }
              return;
            }
            throw err;
          }
          let result;
          try {
            result = await this.workspace.setWorkspacePermissionRules(
              this.wsCtx(conn, method),
              { scope, ruleType, rules }
            );
          } catch (err) {
            if (err instanceof WorkspacePermissionRulesSessionRequiredError && id !== void 0) {
              conn.sendConn(
                error(id, RPC.INVALID_PARAMS, err.message, {
                  errorKind: "permission_session_required"
                })
              );
              return;
            }
            throw err;
          }
          this.replyConn(conn, id, result);
          return;
        }
        case `${QWEN_METHOD_NS}workspace/voice`: {
          const result = await this.workspace.getWorkspaceVoiceStatus(
            this.wsCtx(conn, method)
          );
          this.replyConn(conn, id, result);
          return;
        }
        case `${QWEN_METHOD_NS}workspace/voice/set`: {
          const update = parseWorkspaceVoiceUpdateParams(params);
          if ("error" in update) {
            if (id !== void 0) {
              conn.sendConn(error(id, RPC.INVALID_PARAMS, update.error));
            }
            return;
          }
          const result = await this.workspace.setWorkspaceVoiceSettings(
            this.wsCtx(conn, method),
            update
          );
          this.replyConn(conn, id, result);
          return;
        }
        case `${QWEN_METHOD_NS}workspace/setup-github`: {
          if (params["consent"] !== true) {
            if (id !== void 0) {
              conn.sendConn(
                error(id, RPC.INVALID_PARAMS, "`consent` must be true", {
                  errorKind: "github_setup_consent_required"
                })
              );
            }
            return;
          }
          if (!this.fsFactory) {
            if (id !== void 0) {
              conn.sendConn(
                error(id, RPC.INTERNAL_ERROR, "File system not configured", {
                  errorKind: "internal_error"
                })
              );
            }
            return;
          }
          try {
            const result = await setupGithub({
              cwd: this.boundWorkspace,
              workspaceRoot: this.boundWorkspace,
              proxy: resolveSetupGithubProxy(this.boundWorkspace),
              abortSignal: conn.abortSignal,
              fileOps: createSetupGithubFileOps(
                this.fsFactory,
                `ACP ${method}`,
                conn.clientId
              )
            });
            this.bridge.publishWorkspaceEvent({
              type: "github_setup_completed",
              data: setupGithubEventData(result),
              ...conn.clientId ? { originatorClientId: conn.clientId } : {}
            });
            this.replyConn(conn, id, result);
          } catch (err) {
            if (err instanceof SetupGithubError && id !== void 0) {
              conn.sendConn(
                error(
                  id,
                  err.status >= 500 ? RPC.INTERNAL_ERROR : RPC.INVALID_PARAMS,
                  sanitizeSetupGithubMessage(err.message, this.boundWorkspace),
                  {
                    errorKind: err.code,
                    ...err.partial ? {
                      partial: true,
                      result: err.partialResult ? sanitizeSetupGithubResult(
                        err.partialResult,
                        this.boundWorkspace
                      ) : null
                    } : {}
                  }
                )
              );
              return;
            }
            throw err;
          }
          return;
        }
        case `${QWEN_METHOD_NS}workspace/set_tool_enabled`: {
          const toolName = String(params["toolName"] ?? "");
          if (!toolName || toolName.length > MAX_NAME_LENGTH) {
            if (id !== void 0) {
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  `\`toolName\` is required and must be \u2264 ${MAX_NAME_LENGTH} chars`
                )
              );
            }
            return;
          }
          const result = await this.workspace.setWorkspaceToolEnabled(
            this.wsCtx(conn, method),
            toolName,
            params["enabled"] === true
          );
          this.replyConn(conn, id, result);
          return;
        }
        case `${QWEN_METHOD_NS}workspace/restart_mcp_server`: {
          const serverName = String(params["serverName"] ?? "");
          if (!serverName || serverName.length > MAX_NAME_LENGTH) {
            if (id !== void 0) {
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  `\`serverName\` is required and must be \u2264 ${MAX_NAME_LENGTH} chars`
                )
              );
            }
            return;
          }
          const rawIdx = params["entryIndex"];
          if (rawIdx !== void 0 && (typeof rawIdx !== "number" || !Number.isInteger(rawIdx) || rawIdx < 0)) {
            if (id !== void 0) {
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  "`entryIndex` must be a non-negative integer"
                )
              );
            }
            return;
          }
          const result = await this.workspace.restartMcpServer(
            this.wsCtx(conn, method),
            serverName,
            rawIdx !== void 0 ? { entryIndex: rawIdx } : void 0
          );
          this.replyConn(conn, id, result);
          return;
        }
        // ── Wave 1+2: ACP/REST parity methods ───────────────────────
        case `${QWEN_METHOD_NS}session/recap`: {
          const sessionId = String(params["sessionId"] ?? "");
          await this.withMutableOwned(conn, sessionId, id, async () => {
            const result = await this.bridge.generateSessionRecap(
              sessionId,
              this.sessionCtx(conn, sessionId, loopback)
            );
            this.replyConn(conn, id, result);
          });
          return;
        }
        case `${QWEN_METHOD_NS}session/btw`: {
          const sessionId = String(params["sessionId"] ?? "");
          await this.withMutableOwned(conn, sessionId, id, async () => {
            const rawQ = params["question"];
            if (typeof rawQ !== "string" || rawQ.trim().length === 0 || rawQ.length > BTW_MAX_INPUT_LENGTH) {
              if (id !== void 0)
                conn.sendConn(
                  error(
                    id,
                    RPC.INVALID_PARAMS,
                    `\`question\` required, non-empty, max ${BTW_MAX_INPUT_LENGTH} chars`
                  )
                );
              return;
            }
            const result = await this.bridge.generateSessionBtw(
              sessionId,
              rawQ.trim(),
              void 0,
              this.sessionCtx(conn, sessionId, loopback)
            );
            this.replyConn(conn, id, result);
          });
          return;
        }
        case `${QWEN_METHOD_NS}session/shell`: {
          const sessionId = String(params["sessionId"] ?? "");
          if (!this.sessionShellCommandEnabled) {
            if (id !== void 0) {
              conn.sendConn(rpcErrorFrame(id, new SessionShellDisabledError()));
            }
            return;
          }
          await this.withMutableOwned(conn, sessionId, id, async () => {
            const binding = conn.sessions.get(sessionId);
            const clientId = binding?.clientId;
            if (!clientId) {
              if (id !== void 0) {
                conn.sendConn(
                  rpcErrorFrame(id, new SessionShellClientRequiredError())
                );
              }
              return;
            }
            const rawCmd = params["command"];
            if (typeof rawCmd !== "string" || rawCmd.trim().length === 0) {
              if (id !== void 0)
                conn.sendConn(
                  error(
                    id,
                    RPC.INVALID_PARAMS,
                    "`command` required and must be non-empty"
                  )
                );
              return;
            }
            const logSessionId = logSafe(sessionId.slice(0, 8));
            const logClientId = logSafe(String(conn.clientId?.slice(0, 8)));
            const logCommand = logSafe(rawCmd.slice(0, 120));
            writeStderrLine(
              `qwen serve: /acp session/shell session=${logSessionId} client=${logClientId} cmd=${logCommand}`
            );
            const result = await this.bridge.executeShellCommand(
              sessionId,
              rawCmd,
              binding.abort.signal,
              this.sessionCtx(conn, sessionId, loopback)
            );
            this.replyConn(conn, id, result);
          });
          return;
        }
        case `${QWEN_METHOD_NS}session/detach`: {
          const sessionId = String(params["sessionId"] ?? "");
          await this.withMutableOwned(conn, sessionId, id, async () => {
            const ctx = this.sessionCtx(conn, sessionId, loopback);
            await this.bridge.detachClient(sessionId, ctx.clientId);
            this.replyConn(conn, id, { ok: true });
          });
          return;
        }
        case `${QWEN_METHOD_NS}session/context_usage`: {
          const sessionId = String(params["sessionId"] ?? "");
          if (!this.requireOwned(conn, sessionId, id)) return;
          const result = await this.bridge.getSessionContextUsageStatus(
            sessionId,
            { detail: params["detail"] === true }
          );
          this.replyConn(conn, id, result);
          return;
        }
        case `${QWEN_METHOD_NS}session/tasks`: {
          const sessionId = String(params["sessionId"] ?? "");
          if (!this.requireOwned(conn, sessionId, id)) return;
          const result = await this.bridge.getSessionTasksStatus(sessionId);
          this.replyConn(conn, id, result);
          return;
        }
        case `${QWEN_METHOD_NS}session/lsp`: {
          const sessionId = String(params["sessionId"] ?? "");
          if (!this.requireOwned(conn, sessionId, id)) return;
          const result = await this.bridge.getSessionLspStatus(sessionId);
          this.replyConn(conn, id, result);
          return;
        }
        case `${QWEN_METHOD_NS}session/artifacts`: {
          const sessionId = String(params["sessionId"] ?? "");
          if (!this.requireOwned(conn, sessionId, id)) return;
          const result = await this.bridge.getSessionArtifacts(
            sessionId,
            this.sessionCtx(conn, sessionId, loopback)
          );
          this.replyConn(conn, id, result);
          return;
        }
        case `${QWEN_METHOD_NS}session/artifacts/add`: {
          const sessionId = String(params["sessionId"] ?? "");
          await this.withMutableOwned(conn, sessionId, id, async () => {
            const result = await this.bridge.addSessionArtifact(
              sessionId,
              pickSessionArtifactInput(params),
              this.sessionCtx(conn, sessionId, loopback)
            );
            this.replyConn(conn, id, result);
          });
          return;
        }
        case `${QWEN_METHOD_NS}session/artifacts/remove`: {
          const sessionId = String(params["sessionId"] ?? "");
          await this.withMutableOwned(conn, sessionId, id, async () => {
            const artifactId = String(params["artifactId"] ?? "");
            if (!artifactId) {
              if (id !== void 0) {
                conn.sendConn(
                  error(id, RPC.INVALID_PARAMS, "`artifactId` is required")
                );
              }
              return;
            }
            const result = await this.bridge.removeSessionArtifact(
              sessionId,
              artifactId,
              this.sessionCtx(conn, sessionId, loopback)
            );
            this.replyConn(conn, id, result);
          });
          return;
        }
        case `${QWEN_METHOD_NS}workspace/memory`: {
          const result = await collectWorkspaceMemoryStatus(
            this.boundWorkspace
          );
          this.replyConn(conn, id, result);
          return;
        }
        case `${QWEN_METHOD_NS}workspace/memory/write`: {
          const content = params["content"];
          if (typeof content !== "string") {
            if (id !== void 0)
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  "`content` required, must be string"
                )
              );
            return;
          }
          if (Buffer.byteLength(content, "utf8") > 1024 * 1024) {
            if (id !== void 0)
              conn.sendConn(
                error(id, RPC.INVALID_PARAMS, "`content` exceeds 1MB limit")
              );
            return;
          }
          const rawScope = params["scope"];
          if (rawScope !== void 0 && rawScope !== "workspace" && rawScope !== "global") {
            if (id !== void 0)
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  '`scope` must be "workspace" or "global"'
                )
              );
            return;
          }
          const scope = rawScope ?? "workspace";
          const rawMode = params["mode"];
          if (rawMode !== void 0 && rawMode !== "append" && rawMode !== "replace") {
            if (id !== void 0)
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  '`mode` must be "append" or "replace"'
                )
              );
            return;
          }
          const mode = rawMode ?? "append";
          writeStderrLine(
            `qwen serve: /acp workspace/memory/write scope=${scope} mode=${mode} client=${conn.clientId?.slice(0, 8)} bytes=${Buffer.byteLength(content, "utf8")}`
          );
          const wr = await writeWorkspaceContextFile({
            scope,
            mode,
            content,
            projectRoot: this.boundWorkspace
          });
          this.replyConn(conn, id, {
            ok: true,
            filePath: wr.filePath,
            bytesWritten: wr.bytesWritten,
            changed: wr.changed
          });
          if (wr.changed) {
            try {
              this.bridge.publishWorkspaceEvent({
                type: "memory_changed",
                data: {
                  scope,
                  filePath: wr.filePath,
                  mode,
                  bytesWritten: wr.bytesWritten
                },
                originatorClientId: conn.clientId
              });
            } catch {
            }
          }
          return;
        }
        case `${QWEN_METHOD_NS}workspace/memory/remember`: {
          const content = params["content"];
          if (typeof content !== "string" || !content.trim()) {
            if (id !== void 0) {
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  "`content` must be a non-empty string"
                )
              );
            }
            return;
          }
          if (Buffer.byteLength(content, "utf8") > MAX_REMEMBER_CONTENT_BYTES) {
            if (id !== void 0) {
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  `\`content\` exceeds the ${MAX_REMEMBER_CONTENT_BYTES}-byte limit`
                )
              );
            }
            return;
          }
          const rawContextMode = params["contextMode"] ?? "workspace";
          if (rawContextMode !== "workspace" && rawContextMode !== "clean") {
            if (id !== void 0) {
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  '`contextMode` must be "workspace", "clean", or omitted'
                )
              );
            }
            return;
          }
          try {
            const available = await this.bridge.isWorkspaceMemoryRememberAvailable();
            if (!available) {
              if (id !== void 0) {
                conn.sendConn(
                  error(
                    id,
                    -32009,
                    "Managed memory is unavailable for this daemon workspace",
                    {
                      errorKind: "managed_memory_unavailable",
                      httpStatus: 409
                    }
                  )
                );
              }
              return;
            }
            const task = this.workspaceRememberLane.enqueue({
              content: content.trim(),
              contextMode: rawContextMode,
              ...conn.clientId ? { originatorClientId: conn.clientId } : {}
            });
            this.replyConn(conn, id, task);
          } catch (err) {
            const code = extractRememberErrorCode(err);
            if (id !== void 0) {
              conn.sendConn(
                error(id, -32099, publicErrorMessage(code, "remember"), {
                  errorKind: code,
                  httpStatus: publicErrorStatus(code)
                })
              );
            } else {
              debugLogger2.warn(
                "workspace memory remember notification failed:",
                err
              );
            }
          }
          return;
        }
        case `${QWEN_METHOD_NS}workspace/memory/remember/get`: {
          const taskId = params["taskId"];
          if (typeof taskId !== "string" || taskId.length === 0) {
            if (id !== void 0) {
              conn.sendConn(error(id, RPC.INVALID_PARAMS, "`taskId` required"));
            }
            return;
          }
          const task = this.workspaceRememberLane.get(
            taskId,
            conn.clientId,
            "remember"
          );
          if (!task) {
            if (id !== void 0) {
              conn.sendConn(
                error(id, -32004, "Workspace memory remember task not found", {
                  errorKind: "remember_task_not_found",
                  httpStatus: 404
                })
              );
            }
            return;
          }
          this.replyConn(conn, id, task);
          return;
        }
        case `${QWEN_METHOD_NS}workspace/memory/forget`: {
          const query = params["query"];
          const trimmedQuery = typeof query === "string" ? query.trim() : "";
          if (!trimmedQuery) {
            if (id !== void 0) {
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  "`query` must be a non-empty string"
                )
              );
            }
            return;
          }
          if (Buffer.byteLength(trimmedQuery, "utf8") > MAX_REMEMBER_CONTENT_BYTES) {
            if (id !== void 0) {
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  `\`query\` exceeds the ${MAX_REMEMBER_CONTENT_BYTES}-byte limit`
                )
              );
            }
            return;
          }
          try {
            const available = await this.bridge.isWorkspaceMemoryRememberAvailable();
            if (!available) {
              if (id !== void 0) {
                conn.sendConn(
                  error(
                    id,
                    -32009,
                    "Managed memory is unavailable for this daemon workspace",
                    {
                      errorKind: "managed_memory_unavailable",
                      httpStatus: 409
                    }
                  )
                );
              }
              return;
            }
            const task = this.workspaceRememberLane.enqueueForget({
              query: trimmedQuery,
              ...conn.clientId ? { originatorClientId: conn.clientId } : {}
            });
            this.replyConn(conn, id, task);
          } catch (err) {
            const code = extractRememberErrorCode(err, "forget_failed");
            if (id !== void 0) {
              conn.sendConn(
                error(id, -32099, publicErrorMessage(code, "forget"), {
                  errorKind: code,
                  httpStatus: publicErrorStatus(code)
                })
              );
            } else {
              debugLogger2.warn(
                "workspace memory forget notification failed:",
                err
              );
            }
          }
          return;
        }
        case `${QWEN_METHOD_NS}workspace/memory/forget/get`: {
          const taskId = params["taskId"];
          if (typeof taskId !== "string" || taskId.length === 0) {
            if (id !== void 0) {
              conn.sendConn(error(id, RPC.INVALID_PARAMS, "`taskId` required"));
            }
            return;
          }
          const task = this.workspaceRememberLane.get(
            taskId,
            conn.clientId,
            "forget"
          );
          if (!task) {
            if (id !== void 0) {
              conn.sendConn(
                error(id, -32004, "Workspace memory forget task not found", {
                  errorKind: "forget_task_not_found",
                  httpStatus: 404
                })
              );
            }
            return;
          }
          this.replyConn(conn, id, task);
          return;
        }
        case `${QWEN_METHOD_NS}workspace/memory/dream`: {
          try {
            const available = await this.bridge.isWorkspaceMemoryRememberAvailable();
            if (!available) {
              if (id !== void 0) {
                conn.sendConn(
                  error(
                    id,
                    -32009,
                    "Managed memory is unavailable for this daemon workspace",
                    {
                      errorKind: "managed_memory_unavailable",
                      httpStatus: 409
                    }
                  )
                );
              }
              return;
            }
            const task = this.workspaceRememberLane.enqueueDream({
              ...conn.clientId ? { originatorClientId: conn.clientId } : {}
            });
            this.replyConn(conn, id, task);
          } catch (err) {
            const code = extractRememberErrorCode(err, "dream_failed");
            if (id !== void 0) {
              conn.sendConn(
                error(id, -32099, publicErrorMessage(code, "dream"), {
                  errorKind: code,
                  httpStatus: publicErrorStatus(code)
                })
              );
            } else {
              debugLogger2.warn(
                "workspace memory dream notification failed:",
                err
              );
            }
          }
          return;
        }
        case `${QWEN_METHOD_NS}workspace/memory/dream/get`: {
          const taskId = params["taskId"];
          if (typeof taskId !== "string" || taskId.length === 0) {
            if (id !== void 0) {
              conn.sendConn(error(id, RPC.INVALID_PARAMS, "`taskId` required"));
            }
            return;
          }
          const task = this.workspaceRememberLane.get(
            taskId,
            conn.clientId,
            "dream"
          );
          if (!task) {
            if (id !== void 0) {
              conn.sendConn(
                error(id, -32004, "Workspace memory dream task not found", {
                  errorKind: "dream_task_not_found",
                  httpStatus: 404
                })
              );
            }
            return;
          }
          this.replyConn(conn, id, task);
          return;
        }
        case `${QWEN_METHOD_NS}file/read`: {
          const p = String(params["path"] ?? "");
          if (!p) {
            if (id !== void 0)
              conn.sendConn(error(id, RPC.INVALID_PARAMS, "`path` required"));
            return;
          }
          if (!this.fsFactory) {
            if (id !== void 0)
              conn.sendConn(
                error(id, RPC.INTERNAL_ERROR, "File system not configured")
              );
            return;
          }
          const fs3 = this.fsFactory.forRequest({
            originatorClientId: conn.clientId,
            route: `ACP ${method}`
          });
          const maxBytes = parseOptionalSafeIntegerInRange(
            params["maxBytes"],
            1,
            MAX_READ_BYTES
          );
          if (maxBytes === null) {
            if (id !== void 0)
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  `\`maxBytes\` must be a positive integer in [1, ${MAX_READ_BYTES}]`
                )
              );
            return;
          }
          const line = parseOptionalSafeIntegerInRange(
            params["line"],
            1,
            Number.MAX_SAFE_INTEGER
          );
          if (line === null) {
            if (id !== void 0)
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  "`line` must be a positive integer"
                )
              );
            return;
          }
          const limit = parseOptionalSafeIntegerInRange(
            params["limit"],
            1,
            MAX_FILE_LINE_LIMIT2
          );
          if (limit === null) {
            if (id !== void 0)
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  `\`limit\` must be a positive integer in [1, ${MAX_FILE_LINE_LIMIT2}]`
                )
              );
            return;
          }
          const resolved = await fs3.resolve(p, "read");
          const out = await fs3.readText(resolved, { maxBytes, line, limit });
          this.replyConn(conn, id, {
            path: p,
            content: out.content,
            ...out.meta
          });
          return;
        }
        case `${QWEN_METHOD_NS}file/read_bytes`: {
          if (!this.fsFactory) {
            if (id !== void 0)
              conn.sendConn(
                error(id, RPC.INTERNAL_ERROR, "File system not configured")
              );
            return;
          }
          const p = String(params["path"] ?? "");
          if (!p) {
            if (id !== void 0)
              conn.sendConn(error(id, RPC.INVALID_PARAMS, "`path` required"));
            return;
          }
          const fs3 = this.fsFactory.forRequest({
            originatorClientId: conn.clientId,
            route: `ACP ${method}`
          });
          const offset = parseOptionalSafeIntegerInRange(
            params["offset"],
            0,
            Number.MAX_SAFE_INTEGER
          );
          if (offset === null) {
            if (id !== void 0)
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  "`offset` must be a non-negative safe integer"
                )
              );
            return;
          }
          const maxBytes = parseOptionalSafeIntegerInRange(
            params["maxBytes"],
            1,
            MAX_READ_BYTES
          );
          if (maxBytes === null) {
            if (id !== void 0)
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  `\`maxBytes\` must be a positive integer in [1, ${MAX_READ_BYTES}]`
                )
              );
            return;
          }
          const resolved = await fs3.resolve(p, "read");
          const buf = await fs3.readBytesWindow(resolved, { offset, maxBytes });
          this.replyConn(conn, id, { path: p, ...buf });
          return;
        }
        case `${QWEN_METHOD_NS}file/stat`: {
          if (!this.fsFactory) {
            if (id !== void 0)
              conn.sendConn(
                error(id, RPC.INTERNAL_ERROR, "File system not configured")
              );
            return;
          }
          const p = String(params["path"] ?? "");
          if (!p) {
            if (id !== void 0)
              conn.sendConn(error(id, RPC.INVALID_PARAMS, "`path` required"));
            return;
          }
          const fs3 = this.fsFactory.forRequest({
            originatorClientId: conn.clientId,
            route: `ACP ${method}`
          });
          const resolved = await fs3.resolve(p, "read");
          const result = await fs3.stat(resolved);
          this.replyConn(conn, id, { path: p, ...result });
          return;
        }
        case `${QWEN_METHOD_NS}file/list`: {
          if (!this.fsFactory) {
            if (id !== void 0)
              conn.sendConn(
                error(id, RPC.INTERNAL_ERROR, "File system not configured")
              );
            return;
          }
          const p = String(params["path"] ?? "");
          if (!p) {
            if (id !== void 0)
              conn.sendConn(error(id, RPC.INVALID_PARAMS, "`path` required"));
            return;
          }
          const fs3 = this.fsFactory.forRequest({
            originatorClientId: conn.clientId,
            route: `ACP ${method}`
          });
          const resolved = await fs3.resolve(p, "read");
          const MAX_LIST = 2e3;
          const entries = await fs3.list(resolved, { maxEntries: MAX_LIST + 1 });
          const truncated = entries.length > MAX_LIST;
          this.replyConn(conn, id, {
            path: p,
            entries: truncated ? entries.slice(0, MAX_LIST) : entries,
            truncated
          });
          return;
        }
        case `${QWEN_METHOD_NS}file/glob`: {
          const pattern = String(params["pattern"] ?? "");
          if (!pattern) {
            if (id !== void 0)
              conn.sendConn(
                error(id, RPC.INVALID_PARAMS, "`pattern` required")
              );
            return;
          }
          if (!this.fsFactory) {
            if (id !== void 0)
              conn.sendConn(
                error(id, RPC.INTERNAL_ERROR, "File system not configured")
              );
            return;
          }
          const fs3 = this.fsFactory.forRequest({
            originatorClientId: conn.clientId,
            route: `ACP ${method}`
          });
          const maxResults = parseOptionalPositiveInteger(
            params["maxResults"],
            DEFAULT_FILE_GLOB_MAX_RESULTS,
            MAX_FILE_GLOB_MAX_RESULTS
          );
          if (maxResults === null) {
            if (id !== void 0)
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  "`maxResults` must be an integer between 1 and 50000"
                )
              );
            return;
          }
          const matches = await fs3.glob(pattern, {
            maxResults: maxResults + 1
          });
          const truncated = matches.length > maxResults;
          this.replyConn(conn, id, {
            pattern,
            matches: truncated ? matches.slice(0, maxResults) : matches,
            truncated
          });
          return;
        }
        case `${QWEN_METHOD_NS}file/write`: {
          const p = String(params["path"] ?? "");
          if (!p) {
            if (id !== void 0)
              conn.sendConn(error(id, RPC.INVALID_PARAMS, "`path` required"));
            return;
          }
          if (typeof params["content"] !== "string") {
            if (id !== void 0)
              conn.sendConn(
                error(id, RPC.INVALID_PARAMS, "`content` must be string")
              );
            return;
          }
          if (!this.fsFactory) {
            if (id !== void 0)
              conn.sendConn(
                error(id, RPC.INTERNAL_ERROR, "File system not configured")
              );
            return;
          }
          const fs3 = this.fsFactory.forRequest({
            originatorClientId: conn.clientId,
            route: `ACP ${method}`
          });
          const resolved = await fs3.resolve(p, "write");
          if (Buffer.byteLength(params["content"], "utf8") > 10 * 1024 * 1024) {
            if (id !== void 0)
              conn.sendConn(
                error(id, RPC.INVALID_PARAMS, "content exceeds 10MB limit")
              );
            return;
          }
          await fs3.writeTextOverwrite(resolved, params["content"]);
          this.replyConn(conn, id, { ok: true, path: p });
          return;
        }
        case `${QWEN_METHOD_NS}file/edit`: {
          const p = String(params["path"] ?? "");
          if (!p) {
            if (id !== void 0)
              conn.sendConn(error(id, RPC.INVALID_PARAMS, "`path` required"));
            return;
          }
          if (typeof params["oldText"] !== "string" || typeof params["newText"] !== "string") {
            if (id !== void 0)
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  "`oldText` and `newText` must be strings"
                )
              );
            return;
          }
          if (!this.fsFactory) {
            if (id !== void 0)
              conn.sendConn(
                error(id, RPC.INTERNAL_ERROR, "File system not configured")
              );
            return;
          }
          const fs3 = this.fsFactory.forRequest({
            originatorClientId: conn.clientId,
            route: `ACP ${method}`
          });
          const resolved = await fs3.resolve(p, "write");
          const result = await fs3.edit(
            resolved,
            params["oldText"],
            params["newText"]
          );
          this.replyConn(conn, id, { ok: true, path: p, ...result });
          return;
        }
        case `${QWEN_METHOD_NS}workspace/auth/status`: {
          if (!this.deviceFlowRegistry) {
            this.replyConn(conn, id, { pendingDeviceFlows: [] });
            return;
          }
          const pending = this.deviceFlowRegistry.listPending();
          const projected = pending.map((v) => ({
            deviceFlowId: v.deviceFlowId,
            providerId: v.providerId,
            expiresAt: v.expiresAt
          }));
          this.replyConn(conn, id, { pendingDeviceFlows: projected });
          return;
        }
        case `${QWEN_METHOD_NS}workspace/auth/device_flow/start`: {
          if (!this.deviceFlowRegistry) {
            if (id !== void 0)
              conn.sendConn(
                error(id, RPC.INTERNAL_ERROR, "Device flow not configured")
              );
            return;
          }
          const providerId = String(params["providerId"] ?? "");
          if (!providerId) {
            if (id !== void 0)
              conn.sendConn(
                error(id, RPC.INVALID_PARAMS, "`providerId` required")
              );
            return;
          }
          const startResult = await this.deviceFlowRegistry.start({
            providerId,
            initiatorClientId: conn.clientId
          });
          const { view, attached } = startResult;
          const gated = view.initiatorClientId === conn.clientId ? view : {
            deviceFlowId: view.deviceFlowId,
            providerId: view.providerId,
            status: view.status,
            expiresAt: view.expiresAt
          };
          this.replyConn(conn, id, { view: gated, attached });
          return;
        }
        case `${QWEN_METHOD_NS}workspace/auth/device_flow/get`: {
          if (!this.deviceFlowRegistry) {
            if (id !== void 0)
              conn.sendConn(
                error(id, RPC.INTERNAL_ERROR, "Device flow not configured")
              );
            return;
          }
          const flowId = String(params["id"] ?? "");
          if (!flowId) {
            if (id !== void 0)
              conn.sendConn(error(id, RPC.INVALID_PARAMS, "`id` required"));
            return;
          }
          const view = this.deviceFlowRegistry.get(flowId);
          if (!view) {
            if (id !== void 0)
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  `Device flow "${flowId}" not found`
                )
              );
            return;
          }
          const gated = view.initiatorClientId === conn.clientId ? view : {
            deviceFlowId: view.deviceFlowId,
            providerId: view.providerId,
            status: view.status,
            expiresAt: view.expiresAt
          };
          this.replyConn(conn, id, gated);
          return;
        }
        case `${QWEN_METHOD_NS}workspace/auth/device_flow/cancel`: {
          if (!this.deviceFlowRegistry) {
            if (id !== void 0)
              conn.sendConn(
                error(id, RPC.INTERNAL_ERROR, "Device flow not configured")
              );
            return;
          }
          const flowId = String(params["id"] ?? "");
          if (!flowId) {
            if (id !== void 0)
              conn.sendConn(error(id, RPC.INVALID_PARAMS, "`id` required"));
            return;
          }
          const flowView = this.deviceFlowRegistry.get(flowId);
          if (flowView && flowView.initiatorClientId && flowView.initiatorClientId !== conn.clientId) {
            if (id !== void 0)
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  "Only the flow initiator can cancel"
                )
              );
            return;
          }
          const cancelResult = this.deviceFlowRegistry.cancel(
            flowId,
            conn.clientId
          );
          if (!cancelResult) {
            if (id !== void 0)
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  `Device flow "${flowId}" not found`
                )
              );
            return;
          }
          this.replyConn(conn, id, {
            ok: true,
            alreadyTerminal: cancelResult.alreadyTerminal
          });
          return;
        }
        case `${QWEN_METHOD_NS}workspace/tools`: {
          const result = await this.bridge.getWorkspaceToolsStatus();
          this.replyConn(conn, id, result);
          return;
        }
        case `${QWEN_METHOD_NS}workspace/mcp/tools`: {
          const serverName = String(params["serverName"] ?? "");
          if (!serverName) {
            if (id !== void 0)
              conn.sendConn(
                error(id, RPC.INVALID_PARAMS, "`serverName` required")
              );
            return;
          }
          const result = await this.bridge.getWorkspaceMcpToolsStatus(serverName);
          this.replyConn(conn, id, result);
          return;
        }
        case `${QWEN_METHOD_NS}workspace/mcp/resources`: {
          const serverName = String(params["serverName"] ?? "");
          if (!serverName) {
            if (id !== void 0)
              conn.sendConn(
                error(id, RPC.INVALID_PARAMS, "`serverName` required")
              );
            return;
          }
          const result = await this.bridge.getWorkspaceMcpResourcesStatus(serverName);
          this.replyConn(conn, id, result);
          return;
        }
        case `${QWEN_METHOD_NS}workspace/mcp/servers/add`: {
          const name = String(params["name"] ?? "");
          if (!name || name.length > MAX_NAME_LENGTH) {
            if (id !== void 0)
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  `\`name\` required, max ${MAX_NAME_LENGTH} chars`
                )
              );
            return;
          }
          const config = params["config"];
          if (!config || typeof config !== "object" || Array.isArray(config)) {
            if (id !== void 0)
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  "`config` required, must be object"
                )
              );
            return;
          }
          const result = await this.bridge.addRuntimeMcpServer(
            name,
            config,
            conn.clientId
          );
          this.replyConn(conn, id, result);
          return;
        }
        case `${QWEN_METHOD_NS}workspace/mcp/servers/remove`: {
          const name = String(params["name"] ?? "");
          if (!name || name.length > MAX_NAME_LENGTH) {
            if (id !== void 0)
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  `\`name\` required, max ${MAX_NAME_LENGTH} chars`
                )
              );
            return;
          }
          const result = await this.bridge.removeRuntimeMcpServer(
            name,
            conn.clientId
          );
          this.replyConn(conn, id, result);
          return;
        }
        case `${QWEN_METHOD_NS}sessions/delete`: {
          const ids = this.parseSessionIds(params);
          const svc = new SessionService(this.boundWorkspace);
          const result = await deleteDaemonSessions({
            sessionIds: ids,
            service: svc,
            bridge: this.bridge,
            coordinator: this.archiveCoordinator,
            onError: /* @__PURE__ */ __name(({ phase, sessionId, error: error2 }) => {
              const safeSessionId = logSafe(sessionId.slice(0, 8));
              const safeMessage = logSafe(error2);
              writeStderrLine(
                `qwen serve: /acp sessions/delete ${phase}Session(${safeSessionId}) failed: ${safeMessage}`
              );
            }, "onError")
          });
          this.replyConn(conn, id, result);
          return;
        }
        case `${QWEN_METHOD_NS}sessions/archive`: {
          const ids = this.parseSessionIds(params);
          const svc = new SessionService(this.boundWorkspace, {
            onWarning: logSessionArchiveWarning
          });
          const result = await archiveDaemonSessions({
            sessionIds: ids,
            service: svc,
            bridge: this.bridge,
            coordinator: this.archiveCoordinator
          });
          this.replyConn(conn, id, {
            archived: result.archived,
            alreadyArchived: result.alreadyArchived,
            notFound: result.notFound,
            errors: this.serializeSessionErrors(result.errors)
          });
          return;
        }
        case `${QWEN_METHOD_NS}sessions/unarchive`: {
          const ids = this.parseSessionIds(params);
          const svc = new SessionService(this.boundWorkspace, {
            onWarning: logSessionArchiveWarning
          });
          const result = await unarchiveDaemonSessions({
            sessionIds: ids,
            service: svc,
            coordinator: this.archiveCoordinator
          });
          this.replyConn(conn, id, {
            unarchived: result.unarchived,
            alreadyActive: result.alreadyActive,
            notFound: result.notFound,
            errors: this.serializeSessionErrors(result.errors)
          });
          return;
        }
        case `${QWEN_METHOD_NS}workspace/agents/list`: {
          const agents = await this.agentManager.listSubagents({ force: true });
          this.replyConn(conn, id, {
            v: 1,
            workspaceCwd: this.boundWorkspace,
            agents: agents.map(toSummary)
          });
          return;
        }
        case `${QWEN_METHOD_NS}workspace/agents/get`: {
          const agentType = String(params["agentType"] ?? "");
          if (!agentType) {
            if (id !== void 0)
              conn.sendConn(
                error(id, RPC.INVALID_PARAMS, "`agentType` required")
              );
            return;
          }
          const config = await this.agentManager.loadSubagent(agentType);
          if (!config) {
            if (id !== void 0)
              conn.sendConn(
                error(id, RPC.INVALID_PARAMS, `Agent "${agentType}" not found`)
              );
            return;
          }
          this.replyConn(conn, id, toDetail(config));
          return;
        }
        case `${QWEN_METHOD_NS}workspace/agents/create`: {
          const scope = params["scope"];
          if (scope !== "workspace" && scope !== "global") {
            if (id !== void 0)
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  '`scope` must be "workspace" or "global"'
                )
              );
            return;
          }
          const name = params["name"];
          if (typeof name !== "string" || !name.trim()) {
            if (id !== void 0)
              conn.sendConn(error(id, RPC.INVALID_PARAMS, "`name` required"));
            return;
          }
          const level = scope === "workspace" ? "project" : "user";
          if (BuiltinAgentRegistry.isBuiltinAgent(name)) {
            if (id !== void 0)
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  `Cannot shadow built-in agent "${name}"`
                )
              );
            return;
          }
          const collision = await this.agentManager.loadSubagent(name, level);
          if (collision) {
            if (id !== void 0)
              conn.sendConn(
                error(id, RPC.INVALID_PARAMS, `Agent "${name}" already exists`)
              );
            return;
          }
          await this.agentManager.createSubagent(
            {
              name,
              level,
              description: typeof params["description"] === "string" ? params["description"] : "",
              systemPrompt: typeof params["systemPrompt"] === "string" ? params["systemPrompt"] : "",
              tools: Array.isArray(params["tools"]) ? params["tools"] : void 0,
              model: typeof params["model"] === "string" ? params["model"] : void 0
            },
            { level }
          );
          const created = await this.agentManager.loadSubagent(name, level);
          this.replyConn(conn, id, {
            ok: true,
            agent: created ? toDetail(created) : null
          });
          try {
            this.bridge.publishWorkspaceEvent({
              type: "agent_changed",
              data: { change: "created", name, level },
              originatorClientId: conn.clientId
            });
          } catch {
          }
          return;
        }
        case `${QWEN_METHOD_NS}workspace/agents/update`: {
          const agentType = String(params["agentType"] ?? "");
          if (!agentType) {
            if (id !== void 0)
              conn.sendConn(
                error(id, RPC.INVALID_PARAMS, "`agentType` required")
              );
            return;
          }
          const existing = await this.agentManager.loadSubagent(agentType);
          if (!existing) {
            if (id !== void 0)
              conn.sendConn(
                error(id, RPC.INVALID_PARAMS, `Agent "${agentType}" not found`)
              );
            return;
          }
          const MAX_FIELD_BYTES = 256 * 1024;
          const updates = {};
          if (typeof params["description"] === "string") {
            if (Buffer.byteLength(params["description"], "utf8") > MAX_FIELD_BYTES) {
              if (id !== void 0)
                conn.sendConn(
                  error(
                    id,
                    RPC.INVALID_PARAMS,
                    "`description` exceeds 256KB limit"
                  )
                );
              return;
            }
            updates["description"] = params["description"];
          }
          if (typeof params["systemPrompt"] === "string") {
            if (Buffer.byteLength(params["systemPrompt"], "utf8") > MAX_FIELD_BYTES) {
              if (id !== void 0)
                conn.sendConn(
                  error(
                    id,
                    RPC.INVALID_PARAMS,
                    "`systemPrompt` exceeds 256KB limit"
                  )
                );
              return;
            }
            updates["systemPrompt"] = params["systemPrompt"];
          }
          if (Array.isArray(params["tools"])) {
            if (params["tools"].length > 256) {
              if (id !== void 0)
                conn.sendConn(
                  error(
                    id,
                    RPC.INVALID_PARAMS,
                    "`tools` exceeds 256-entry limit"
                  )
                );
              return;
            }
            if (!params["tools"].every(
              (t) => typeof t === "string" && t.length <= 256
            )) {
              if (id !== void 0)
                conn.sendConn(
                  error(
                    id,
                    RPC.INVALID_PARAMS,
                    "`tools` elements must be strings \u2264256 chars"
                  )
                );
              return;
            }
            updates["tools"] = params["tools"];
          }
          if (typeof params["model"] === "string")
            updates["model"] = params["model"];
          if (Object.keys(updates).length === 0) {
            if (id !== void 0)
              conn.sendConn(
                error(
                  id,
                  RPC.INVALID_PARAMS,
                  "at least one updatable field required"
                )
              );
            return;
          }
          await this.agentManager.updateSubagent(
            agentType,
            updates,
            existing.level
          );
          const updated = await this.agentManager.loadSubagent(
            agentType,
            existing.level
          );
          this.replyConn(conn, id, {
            ok: true,
            agent: updated ? toDetail(updated) : null
          });
          try {
            this.bridge.publishWorkspaceEvent({
              type: "agent_changed",
              data: {
                change: "updated",
                name: agentType,
                level: existing.level
              },
              originatorClientId: conn.clientId
            });
          } catch {
          }
          return;
        }
        case `${QWEN_METHOD_NS}workspace/agents/delete`: {
          const agentType = String(params["agentType"] ?? "");
          if (!agentType) {
            if (id !== void 0)
              conn.sendConn(
                error(id, RPC.INVALID_PARAMS, "`agentType` required")
              );
            return;
          }
          const scope = typeof params["scope"] === "string" ? params["scope"] : void 0;
          const level = scope === "workspace" ? "project" : scope === "global" ? "user" : void 0;
          const existing = await this.agentManager.loadSubagent(
            agentType,
            level
          );
          if (!existing) {
            if (id !== void 0)
              conn.sendConn(
                error(id, RPC.INVALID_PARAMS, `Agent "${agentType}" not found`)
              );
            return;
          }
          await this.agentManager.deleteSubagent(agentType, existing.level);
          this.replyConn(conn, id, { ok: true });
          try {
            this.bridge.publishWorkspaceEvent({
              type: "agent_changed",
              data: {
                change: "deleted",
                name: agentType,
                level: existing.level
              },
              originatorClientId: conn.clientId
            });
          } catch {
          }
          return;
        }
        default:
          if (id !== void 0) {
            conn.sendConn(
              error(id, RPC.METHOD_NOT_FOUND, `Unknown method: ${method}`)
            );
          }
          return;
      }
    } catch (err) {
      writeStderrLine(
        `qwen serve: /acp dispatch error (${logSafe(method)}): ${logSafe(errMsg(err))}`
      );
      if (id !== void 0) {
        const { code, message, data } = toRpcError(err);
        const frame = error(id, code, message, data);
        const sessionId = typeof params["sessionId"] === "string" ? params["sessionId"] : void 0;
        if (sessionId && !CONN_ROUTED_METHODS.has(method)) {
          this.replySession(conn, sessionId, id, void 0, frame);
        } else {
          conn.sendConn(frame);
        }
      }
    }
  }
  /**
   * Bind a session-scoped SSE stream to the bridge's event stream,
   * translating each `BridgeEvent` into a JSON-RPC frame (design §4.2).
   */
  async pumpSessionEvents(conn, sessionId, signal, lastEventId) {
    try {
      let lastDeliveredId = lastEventId ?? 0;
      let sawEviction = false;
      let subscribeFromEventId = lastEventId;
      if (conn.hasInitialReplayPending(sessionId)) {
        const snapshot = this.bridge.getSessionReplaySnapshot(sessionId);
        if (snapshot) {
          const snapshotEvents = [
            ...snapshot.compactedTurns,
            ...snapshot.liveJournal
          ];
          for (const event of snapshotEvents) {
            if (signal.aborted) return;
            if (typeof event.id === "number" && event.id <= lastDeliveredId) {
              continue;
            }
            conn.touch();
            this.translateEvent(conn, sessionId, event);
            if (typeof event.id === "number") {
              lastDeliveredId = event.id;
              conn.releaseDeferredSessionReplies(sessionId, event.id);
            }
          }
          if (signal.aborted) return;
          lastDeliveredId = Math.max(lastDeliveredId, snapshot.lastEventId);
          subscribeFromEventId = Math.max(
            subscribeFromEventId ?? 0,
            snapshot.lastEventId
          );
        } else {
          writeStderrLine(
            `qwen serve: /acp initial replay skipped (no snapshot) session=${logSafe(sessionId)}`
          );
          conn.markInitialReplayComplete(sessionId);
          conn.endReplayDeferral(sessionId, lastDeliveredId, false);
        }
      }
      const iterable = this.bridge.subscribeEvents(sessionId, {
        signal,
        ...subscribeFromEventId !== void 0 ? { lastEventId: subscribeFromEventId } : {}
      });
      for await (const event of iterable) {
        if (signal.aborted) break;
        conn.touch();
        this.translateEvent(conn, sessionId, event);
        if (event.type === "state_resync_required") sawEviction = true;
        if (typeof event.id === "number") {
          lastDeliveredId = event.id;
          conn.releaseDeferredSessionReplies(sessionId, event.id);
        }
        if (event.type === "replay_complete") {
          conn.endReplayDeferral(sessionId, lastDeliveredId, sawEviction);
          conn.markInitialReplayComplete(sessionId);
          const replayedCount = event.data?.replayedCount;
          writeStderrLine(
            `qwen serve: /acp replay complete (${logSafe(sessionId)}) from=${lastEventId ?? "none"} delivered_through=${lastDeliveredId} count=${replayedCount ?? "n/a"} evicted=${sawEviction}`
          );
        }
      }
      if (!signal.aborted) conn.flushBufferedSessionFrames(sessionId);
    } catch (err) {
      if (!signal.aborted) {
        conn.flushBufferedSessionFrames(sessionId);
        conn.sendSession(
          sessionId,
          notification(`${QWEN_METHOD_NS}notify`, {
            kind: "stream_error",
            error: errMsg(err)
          })
        );
      }
      throw err;
    }
  }
  translateEvent(conn, sessionId, event) {
    switch (event.type) {
      case "session_update": {
        conn.sendSession(
          sessionId,
          notification("session/update", event.data),
          event.id
        );
        return;
      }
      case "permission_request": {
        const data = event.data;
        const binding = conn.sessions.get(sessionId);
        if (!binding?.stream || binding.stream.isClosed) {
          if (binding?.graceTimer) {
            writeStderrLine(
              `qwen serve: /acp permission cancel during reconnect grace (${logSafe(sessionId)}); vote not deferred (see \xA71.7 follow-up)`
            );
          }
          const cancelled = this.cancelAbandonedPermission(
            { sessionId, bridgeRequestId: data.requestId },
            // Pass the bridge-stamped clientId when the binding still exists
            // (stream closed but session live) — only `undefined` when the
            // session is fully gone.
            binding?.clientId
          );
          if (!cancelled) {
            writeStderrLine(
              `qwen serve: /acp permission cancel FAILED for ${logSafe(sessionId)} (mediator stuck; no automatic recovery)`
            );
          }
          return;
        }
        let id;
        for (const [existingId, p] of conn.pending) {
          if (p.kind === "permission" && p.sessionId === sessionId && p.bridgeRequestId === data.requestId) {
            id = existingId;
            break;
          }
        }
        if (id === void 0) {
          id = conn.nextId();
          conn.pending.set(id, {
            sessionId,
            bridgeRequestId: data.requestId,
            kind: "permission"
          });
        }
        void binding.stream.send(
          request(id, "session/request_permission", {
            sessionId: data.sessionId,
            toolCall: data.toolCall,
            options: data.options,
            _meta: { [QWEN_META_KEY]: { requestId: data.requestId } }
          }),
          // Carry the bus cursor: a permission request is a real sequenced
          // event, so the client must resume past it.
          event.id
        );
        return;
      }
      case "stream_error": {
        conn.sendSession(
          sessionId,
          notification(`${QWEN_METHOD_NS}notify`, {
            // Spread first so a stray `kind` in event.data can't shadow the
            // discriminator the client's error handler keys on.
            ...event.data,
            kind: "stream_error"
          }),
          // Pass the bus cursor through if present; a synthetic terminal frame
          // has no bus id (event.id undefined) so no SSE `id:` line is written.
          event.id
        );
        return;
      }
      default: {
        conn.sendSession(
          sessionId,
          notification(`${QWEN_METHOD_NS}notify`, {
            kind: event.type,
            data: event.data
          }),
          event.id
        );
      }
    }
  }
  /**
   * Resolve a client's JSON-RPC response to an agent→client request.
   * `fromLoopback` is the CURRENT request's loopback bit (the vote POST may
   * arrive from a different peer than `initialize`).
   */
  resolveClientResponse(conn, msg, fromLoopback) {
    const id = msg.id;
    if (typeof id !== "string") return;
    const pendingRef = this.findPendingClientRequest(conn, id);
    if (!pendingRef) return;
    const pendingConn = pendingRef.conn;
    const pending = pendingRef.req;
    if (pendingConn !== conn && !conn.ownsSession(pending.sessionId)) {
      writeStderrLine(
        `qwen serve: /acp permission vote dropped: responding connection ${logSafe(
          conn.connectionId.slice(0, 8)
        )} does not own session ${logSafe(pending.sessionId)} (requestId ${logSafe(
          pending.bridgeRequestId
        )})`
      );
      return;
    }
    try {
      const vote = "error" in msg ? { outcome: { outcome: "cancelled" } } : parsePermissionResponse(
        isObject(msg.result) ? msg.result : {}
      );
      this.bridge.respondToSessionPermission(
        pending.sessionId,
        pending.bridgeRequestId,
        vote,
        this.sessionCtx(conn, pending.sessionId, fromLoopback)
      );
      this.dropResolvedPermission(pendingConn, id);
    } catch (err) {
      writeStderrLine(
        `qwen serve: /acp permission vote failed (${logSafe(pending.sessionId)}): ${logSafe(errMsg(err))}`
      );
      const cancelled = this.cancelAbandonedPermission(
        pending,
        pendingConn.sessions.get(pending.sessionId)?.clientId
      );
      if (cancelled) this.dropResolvedPermission(pendingConn, id);
    }
  }
  async handlePrompt(conn, sessionId, id, params, fromLoopback) {
    const binding = conn.getOrCreateSession(sessionId);
    binding.promptAbort?.abort();
    const abort = new AbortController();
    binding.promptAbort = abort;
    try {
      const result = await this.bridge.sendPrompt(
        sessionId,
        // SECURITY NOTE: `params.sessionId` already equals the routing
        // `sessionId` (both from the same params), so there's no routing
        // divergence today. If the bridge ever trusts an additional
        // `sendPrompt` field by name (e.g. a priority/temperature override),
        // force-stamp it here like the REST surface does (`{ ...body,
        // sessionId, prompt }`) so it can't become client-controlled.
        params,
        abort.signal,
        this.sessionCtx(conn, sessionId, fromLoopback)
      );
      if (id !== void 0) this.replySession(conn, sessionId, id, result);
    } catch (err) {
      const { code, message, data } = toRpcError(err);
      if (id !== void 0) {
        this.replySession(
          conn,
          sessionId,
          id,
          void 0,
          error(id, code, message, data)
        );
      } else {
        writeStderrLine(
          `qwen serve: /acp prompt error (${logSafe(sessionId)}, notification): ${logSafe(errMsg(err))}`
        );
      }
    } finally {
      if (binding.promptAbort === abort) binding.promptAbort = void 0;
    }
  }
  replyConn(conn, id, result) {
    if (id === void 0) return;
    conn.sendConn(success(id, result));
  }
  replySession(conn, sessionId, id, result, errorFrame) {
    if (id === void 0) return;
    const frame = errorFrame ?? success(id, result);
    if (conn.sessions.has(sessionId)) {
      let anchorId;
      try {
        anchorId = this.bridge.getSessionLastEventId(sessionId);
      } catch (err) {
        anchorId = void 0;
        writeStderrLine(
          `qwen serve: /acp replySession(${logSafe(sessionId)}) anchor unavailable, deferring unanchored: ` + logSafe(err instanceof Error ? err.message : String(err))
        );
      }
      conn.sendSessionReply(sessionId, frame, anchorId);
    } else {
      writeStderrLine(
        `qwen serve: /acp replySession(${logSafe(sessionId)}) binding gone mid-flight, reply routed to connection stream ${conn.connectionId.slice(0, 8)}`
      );
      conn.sendConn(frame);
    }
  }
};

// packages/cli/src/serve/acp-http/connection-registry.ts
init_esbuild_shims();
import { randomUUID as randomUUID2 } from "node:crypto";
var MAX_BUFFERED_FRAMES = 256;
var HARD_BUFFERED_FRAMES_CAP = MAX_BUFFERED_FRAMES * 4;
var DEFAULT_MAX_CONNECTIONS = 64;
var AcpConnection = class {
  constructor(connectionId, fromLoopback, onAbandonPending, onDetachSession) {
    this.onAbandonPending = onAbandonPending;
    this.onDetachSession = onDetachSession;
    this.connectionId = connectionId ?? randomUUID2();
    this.clientId = randomUUID2();
    this.fromLoopback = fromLoopback;
  }
  static {
    __name(this, "AcpConnection");
  }
  connectionId;
  /** Connection-scoped SSE stream (the client's `GET /acp` with only the conn header). */
  connStream;
  abortController = new AbortController();
  abortSignal = this.abortController.signal;
  /** Frames emitted before the connection stream attached, flushed on attach. */
  connBuffer = [];
  sessions = /* @__PURE__ */ new Map();
  /**
   * Sessions this connection created (`session/new`) or explicitly
   * attached to (`session/load`/`resume`). Per-session operations
   * (subscribe, prompt, cancel, …) are gated on membership here so one
   * connection can't drive or eavesdrop on a session it never claimed.
   */
  ownedSessions = /* @__PURE__ */ new Set();
  /**
   * Sessions with an in-flight `session/close` (between the synchronous
   * ownership-revoke and the bridge close + local teardown). `session/load`
   * / `resume` reject for an id in this set so a close racing a re-load
   * can't have its `finally` teardown destroy the freshly-loaded session.
   */
  closingSessions = /* @__PURE__ */ new Set();
  /** Agent→client requests awaiting a client response, keyed by JSON-RPC id. */
  pending = /* @__PURE__ */ new Map();
  /** Daemon-issued client id reused across this connection's bridge calls. */
  clientId;
  /**
   * True when the `initialize` POST arrived from a kernel-stamped loopback
   * peer. Threaded into per-session bridge contexts so the `local-only`
   * permission policy can gate votes by transport — mirrors the REST
   * surface's `detectFromLoopback(req)`. NOT derived from forgeable
   * headers (`X-Forwarded-For` etc).
   */
  fromLoopback;
  /**
   * Set by `destroy()`. An in-flight `session/new`/`load`/`resume` whose
   * bridge call resolves AFTER teardown checks this to kill/detach the
   * late-registered session, so a `DELETE` (or idle sweep) racing a spawn
   * doesn't orphan a child process / phantom clientId.
   */
  destroyed = false;
  /**
   * Grace-period reap timer armed when the connection-scoped SSE stream
   * closes; cleared on reconnect (`attachConnStream`) or teardown. Avoids a
   * dead connection locking its `ownedSessions` (and counting against
   * `maxConnections`) for the full 30-min idle TTL.
   */
  connGraceTimer;
  /**
   * True once the connection grace timer has fired. The timer is one-shot, so
   * if it fired while a session was still mid-reconnect (`hasRecoverableSession`
   * blocked the reap), nothing would re-check the connection after that session
   * later tore down — it would linger until the 30-min idle sweep. This flag
   * lets `onSessionGraceExpired` (fired when a session grace expires) recognize
   * "the conn grace already elapsed" and run the reap that was deferred.
   */
  connGraceExpired = false;
  /**
   * Set by the transport layer (`index.ts`) when the connection grace timer is
   * armed. Invoked after a session's reclaim grace expires so a connection that
   * was blocked from reaping by a then-recoverable session gets re-evaluated
   * instead of leaking until the idle sweep.
   */
  onSessionGraceExpired;
  lastActiveMs = Date.now();
  idCounter = 0;
  /**
   * Allocate a fresh JSON-RPC id for an agent→client request. STRING-typed
   * (`_qwen_perm_<conn>_N`) so it can never collide with a client-originated id —
   * JSON-RPC 2.0 permits clients to use any number (incl. negatives) or
   * string, so a numeric namespace wasn't actually safe.
   */
  nextId() {
    this.idCounter += 1;
    return `_qwen_perm_${this.connectionId}_${this.idCounter}`;
  }
  touch() {
    this.lastActiveMs = Date.now();
  }
  ownSession(sessionId) {
    this.ownedSessions.add(sessionId);
  }
  ownsSession(sessionId) {
    return this.ownedSessions.has(sessionId);
  }
  getOrCreateSession(sessionId) {
    let binding = this.sessions.get(sessionId);
    if (!binding) {
      binding = { sessionId, abort: new AbortController(), buffer: [] };
      this.sessions.set(sessionId, binding);
    }
    return binding;
  }
  markInitialReplayPending(sessionId) {
    this.getOrCreateSession(sessionId).initialReplayPending = true;
  }
  hasInitialReplayPending(sessionId) {
    return this.sessions.get(sessionId)?.initialReplayPending === true;
  }
  markInitialReplayComplete(sessionId) {
    const binding = this.sessions.get(sessionId);
    if (binding) binding.initialReplayPending = false;
  }
  getDiagnostic() {
    const liveStreams = /* @__PURE__ */ new Set();
    if (this.connStream && !this.connStream.isClosed) {
      liveStreams.add(this.connStream);
    }
    let sessionStreams = 0;
    let bufferedSessionFrames = 0;
    for (const binding of this.sessions.values()) {
      bufferedSessionFrames += binding.buffer.length;
      if (binding.stream && !binding.stream.isClosed) {
        sessionStreams += 1;
        liveStreams.add(binding.stream);
      }
    }
    let sseStreams = 0;
    let wsStreams = 0;
    for (const stream of liveStreams) {
      if (stream.kind === "sse") sseStreams += 1;
      if (stream.kind === "ws") wsStreams += 1;
    }
    return {
      connectionIdPrefix: this.connectionId.slice(0, 8),
      fromLoopback: this.fromLoopback,
      destroyed: this.destroyed,
      lastActiveMs: this.lastActiveMs,
      ownedSessionCount: this.ownedSessions.size,
      sessionBindingCount: this.sessions.size,
      closingSessionCount: this.closingSessions.size,
      pendingClientRequests: this.pending.size,
      connectionStreamOpen: this.connStream !== void 0 && !this.connStream.isClosed,
      sessionStreams,
      sseStreams,
      wsStreams,
      bufferedConnectionFrames: this.connBuffer.length,
      bufferedSessionFrames
    };
  }
  /** Send a frame on the connection-scoped stream (buffer until it attaches). */
  sendConn(frame) {
    if (this.connStream && !this.connStream.isClosed) {
      void this.connStream.send(frame);
    } else {
      pushCapped(this.connBuffer, frame, `conn ${this.connectionId}`);
    }
  }
  /** True if any session currently has a live (open) SSE stream. */
  hasLiveSessionStream() {
    for (const b of this.sessions.values()) {
      if (b.stream && !b.stream.isClosed) return true;
    }
    return false;
  }
  /**
   * True if any session is mid-reconnect: its transport stream detached but
   * its `SESSION_GRACE_MS` reclaim window is still armed (`graceTimer` set),
   * so the binding — ownership + in-flight prompt — is being held open for an
   * imminent resume. The connection reaper must count these as activity:
   * otherwise, when the connection-scoped stream closes first and a session
   * stream detaches just after, the connection grace timer could delete the
   * whole connection (and `destroy()` abort the prompt) while the session is
   * still inside its OWN grace window — the reconnect would then 404.
   */
  hasRecoverableSession() {
    for (const b of this.sessions.values()) {
      if (b.graceTimer) return true;
    }
    return false;
  }
  /** Cancel a pending grace-period reap (e.g. on conn-stream reconnect). */
  clearGraceTimer() {
    if (this.connGraceTimer) {
      clearTimeout(this.connGraceTimer);
      this.connGraceTimer = void 0;
    }
    this.connGraceExpired = false;
  }
  /** Attach the connection-scoped stream and flush any buffered frames. */
  attachConnStream(stream) {
    this.clearGraceTimer();
    if (this.connStream && this.connStream !== stream) this.connStream.close();
    this.connStream = stream;
    for (const frame of this.connBuffer.splice(0)) void stream.send(frame);
  }
  /**
   * Send a frame on a session-scoped stream (buffer until it attaches).
   * LOOKUP-ONLY: drops the frame when the session has no binding — a binding
   * always exists for a live session (created at `session/new`/`load`/
   * `resume`), so a missing one means the session was torn down. Auto-
   * creating here would resurrect a ghost binding (no stream, no owner) that
   * buffers up to 256 late pump/reply frames forever.
   */
  sendSession(sessionId, frame, id) {
    const binding = this.sessions.get(sessionId);
    if (!binding) return;
    if (binding.stream && !binding.stream.isClosed) {
      void binding.stream.send(frame, id);
    } else {
      pushCapped(
        binding.buffer,
        { frame, id },
        `session ${sessionId}`,
        (e) => e.id
      );
    }
  }
  /**
   * Send an OUT-OF-BAND session JSON-RPC reply (a `session/prompt` result and
   * friends from `replySession`) — id-less on the wire (no ring cursor).
   *
   * Unlike `sendSession`, this defers the reply behind a watermark while a ring
   * replay is catching up. `anchorId` is the bus head id at the moment the reply
   * was produced (every content event that should precede the reply has id ≤
   * `anchorId`). The reply is held until the pump has DELIVERED through that id
   * (`releaseDeferredSessionReplies`), so a prompt that finishes during a slow
   * replay can't land ahead of tail content still queued behind `replay_complete`
   * (§1.8 W1 — the truncated-body reordering).
   *
   * It defers when EITHER a resume replay is in flight (`replayPending`) OR the
   * stream is detached OR replies are already queued ahead of it (`buffer` not
   * empty) — that last case keeps a just-produced reply from overtaking an
   * earlier one still waiting on its watermark. Once the buffer drains and replay
   * is done, replies go straight to the wire (steady state, unchanged from a
   * non-resumed stream).
   */
  sendSessionReply(sessionId, frame, anchorId) {
    const binding = this.sessions.get(sessionId);
    if (!binding) return;
    if (binding.stream && !binding.stream.isClosed && !binding.replayPending && binding.buffer.length === 0) {
      void binding.stream.send(frame);
      return;
    }
    pushCapped(
      binding.buffer,
      { frame, id: void 0, anchorId },
      `session ${sessionId}`,
      (e) => e.id
    );
  }
  /**
   * Release deferred out-of-band replies (`sendSessionReply`) whose watermark
   * (`anchorId`) the pump has now passed: every leading id-less buffer entry
   * with `anchorId ≤ deliveredId` is flushed to the live stream, in order. The
   * pump calls this after delivering each content event (and at `replay_complete`
   * with the last replayed id), so each reply lands immediately AFTER the last
   * content event that preceded it — never ahead of tail content still queued.
   *
   * Stops at the first entry that is id-bearing (not a deferred reply) or whose
   * anchor is still ahead of `deliveredId`, preserving stream order. No-op if the
   * stream isn't live (the entries stay buffered for the next attach).
   */
  releaseDeferredSessionReplies(sessionId, deliveredId) {
    const binding = this.sessions.get(sessionId);
    if (!binding || !binding.stream || binding.stream.isClosed) return;
    while (binding.buffer.length > 0) {
      const front = binding.buffer[0];
      if (front.id !== void 0) break;
      if (front.anchorId === void 0) {
        if (binding.replayPending) break;
      } else if (front.anchorId > deliveredId) {
        break;
      }
      binding.buffer.shift();
      void binding.stream.send(front.frame);
    }
  }
  /**
   * Attach a session-scoped stream: close any prior stream, abort the prior
   * subscription, install the caller's FRESH AbortController (the old one is
   * aborted and can never resume — reusing it would leave the new stream
   * event-starved), flush buffered frames, and return the binding.
   */
  attachSessionStream(sessionId, stream, abort, resumeFromEventId) {
    const binding = this.getOrCreateSession(sessionId);
    if (binding.graceTimer) {
      clearTimeout(binding.graceTimer);
      binding.graceTimer = void 0;
      writeStderrLine(
        `qwen serve: /acp session reclaimed within grace (${logSafe(sessionId)})`
      );
    }
    const prevStream = binding.stream;
    binding.abort.abort();
    binding.abort = abort;
    binding.stream = stream;
    if (prevStream && prevStream !== stream && prevStream !== this.connStream) {
      prevStream.close();
    }
    const replayingOnAttach = resumeFromEventId !== void 0 || binding.initialReplayPending === true;
    binding.replayPending = replayingOnAttach;
    if (binding.replayPending) {
      writeStderrLine(
        `qwen serve: /acp replay deferral armed (${logSafe(sessionId)}, from id ${resumeFromEventId ?? "initial"})`
      );
    }
    const gap = binding.buffer.splice(0);
    for (const entry of gap) {
      if (!replayingOnAttach) {
        void stream.send(entry.frame, entry.id);
      } else if (entry.id !== void 0) {
        continue;
      } else {
        binding.buffer.push(entry);
      }
    }
    return binding;
  }
  /**
   * The ring replay drained (`replay_complete`): stop deferring NEW replies that
   * are anchored within the replayed range, and release every buffered reply
   * whose watermark the replay already passed (`anchorId ≤ lastReplayedId`).
   *
   * Replies anchored ABOVE the replayed range stay buffered — their content
   * hasn't been delivered yet because the turn was still running at reconnect
   * (the content flows as LIVE events after `replay_complete`). The per-event
   * `releaseDeferredSessionReplies` calls drain those as the matching live
   * content arrives, so a result produced during a slow replay still lands after
   * its tail content (§1.8 W1), not at the boundary.
   */
  endReplayDeferral(sessionId, lastReplayedId, evictionOccurred = false) {
    const binding = this.sessions.get(sessionId);
    if (!binding) return;
    binding.replayPending = false;
    if (evictionOccurred) {
      this.flushBufferedSessionFrames(sessionId);
      return;
    }
    this.releaseDeferredSessionReplies(sessionId, lastReplayedId);
  }
  /**
   * Final, UNCONDITIONAL flush of everything still buffered — used when the pump
   * ends with no more events coming (clean iterator end / live-only subscription
   * with no replay boundary). Releases any remaining deferred replies regardless
   * of watermark: their anchored content will never arrive, so holding them
   * would strand the result forever.
   *
   * No-op if the session has no live stream (frames stay buffered for the next
   * attach) — but `replayPending` is cleared regardless, since no replay is in
   * flight once the pump has settled.
   *
   * The frames are enqueued synchronously, in buffer order: `SseStream`
   * serializes every `send` through one `writeChain`, so wire order is fixed by
   * call order here. We deliberately do NOT `await` each `send` between `shift`s
   * — doing so would open a window where a live event arriving mid-drain enqueues
   * BETWEEN two deferred frames, reordering the very replies this deferral exists
   * to keep in order (§1.8 W1).
   */
  flushBufferedSessionFrames(sessionId) {
    const binding = this.sessions.get(sessionId);
    if (!binding) return;
    binding.replayPending = false;
    if (!binding.stream || binding.stream.isClosed || binding.buffer.length === 0)
      return;
    for (const { frame, id } of binding.buffer.splice(0)) {
      void binding.stream.send(frame, id);
    }
  }
  /**
   * Transport-level session-stream close (proxy idle-close / network blip) —
   * as opposed to an explicit `session/close`. Detaches ONLY the stream and
   * its event subscription while KEEPING the binding, ownership, the in-flight
   * prompt, and the bridge-client registration, so a reconnect within
   * `graceMs` can resume (ring replay backfills the gap — §1.8). If no
   * reconnect arrives, the grace timer runs the full `closeSessionStream`
   * teardown, bounding the runaway-prompt cost. Identity-guarded: a stale
   * stream's close can't detach a newer reconnect's stream.
   */
  detachSessionStream(sessionId, stream, graceMs) {
    const binding = this.sessions.get(sessionId);
    if (!binding || binding.stream !== stream) return;
    writeStderrLine(
      `qwen serve: /acp session stream detached (${logSafe(sessionId)}), grace=${graceMs}ms`
    );
    binding.abort.abort();
    binding.stream = void 0;
    if (binding.graceTimer) clearTimeout(binding.graceTimer);
    binding.graceTimer = setTimeout(() => {
      writeStderrLine(
        `qwen serve: /acp session grace expired (${logSafe(sessionId)}), no reconnect within ${graceMs}ms \u2014 tearing down`
      );
      try {
        this.closeSessionStream(sessionId);
      } catch (err) {
        writeStderrLine(
          `qwen serve: /acp teardown failed during grace expiry (${logSafe(sessionId)}): ` + (err instanceof Error ? err.message : String(err))
        );
      }
      try {
        this.onSessionGraceExpired?.();
      } catch (err) {
        writeStderrLine(
          `qwen serve: /acp onSessionGraceExpired failed during grace expiry (${logSafe(sessionId)}): ` + (err instanceof Error ? err.message : String(err))
        );
      }
    }, graceMs);
    binding.graceTimer.unref?.();
  }
  closeSessionStream(sessionId) {
    const binding = this.sessions.get(sessionId);
    if (!binding) return;
    this.teardownBinding(binding);
    this.sessions.delete(sessionId);
    this.ownedSessions.delete(sessionId);
  }
  destroy() {
    this.destroyed = true;
    this.abortController.abort();
    this.clearGraceTimer();
    for (const binding of this.sessions.values()) {
      try {
        this.teardownBinding(binding);
      } catch (err) {
        writeStderrLine(
          `qwen serve: /acp teardownBinding(${logSafe(binding.sessionId)}) failed during destroy: ${err instanceof Error ? err.message : String(err)}`
        );
      }
    }
    this.sessions.clear();
    this.ownedSessions.clear();
    this.pending.clear();
    this.connStream?.close();
  }
  teardownBinding(binding) {
    if (binding.graceTimer) {
      clearTimeout(binding.graceTimer);
      binding.graceTimer = void 0;
    }
    binding.abort.abort();
    binding.promptAbort?.abort();
    if (binding.stream && binding.stream !== this.connStream) {
      binding.stream.close();
    }
    this.abandonPendingForSession(binding.sessionId, binding.clientId);
    this.onDetachSession?.(binding.sessionId, binding.clientId);
  }
  /**
   * Cancel + drop any pending agent→client requests for a closing session.
   * This is the LAST-RESORT recovery path: `resolveClientResponse` retains a
   * pending entry on double-failure (vote AND cancel both threw) precisely so
   * this teardown sweep can retry the cancel. We always drop the entry here
   * (the connection is going away — there is no further retry after teardown),
   * but if the cancel itself still fails (triple-failure) the bridge mediator
   * may be stuck awaiting a vote that will never arrive, so log it for the
   * operator rather than failing silently.
   */
  abandonPendingForSession(sessionId, clientId) {
    for (const [id, req] of this.pending) {
      if (req.sessionId !== sessionId) continue;
      this.pending.delete(id);
      const cancelled = this.onAbandonPending?.(req, clientId) ?? true;
      if (!cancelled) {
        writeStderrLine(
          `qwen serve: /acp MEDIATOR STUCK: abandonPendingForSession(${logSafe(sessionId)}) cancel failed for ${logSafe(req.bridgeRequestId)}`
        );
      }
    }
  }
};
function pushCapped(buf, frame, label = "stream", getId) {
  if (buf.length >= MAX_BUFFERED_FRAMES) {
    const replayable = getId ? buf.findIndex((e) => getId(e) !== void 0) : 0;
    if (replayable === -1) {
      if (buf.length >= HARD_BUFFERED_FRAMES_CAP) {
        buf.shift();
        writeStderrLine(
          `qwen serve: /acp HARD buffer cap breached (${label}) \u2014 dropping oldest id-less reply (its caller may hang); buffer was ${buf.length + 1}`
        );
      } else if (buf.length === MAX_BUFFERED_FRAMES) {
        writeStderrLine(
          `qwen serve: /acp pre-attach buffer over soft cap (${label}) \u2014 id-less replies are irreplaceable, not dropping`
        );
      }
    } else {
      const [dropped] = buf.splice(replayable, 1);
      const droppedId = getId?.(dropped);
      writeStderrLine(
        `qwen serve: /acp pre-attach buffer full (${label}), dropped frame` + (droppedId !== void 0 ? ` id ${droppedId}` : "")
      );
    }
  }
  buf.push(frame);
}
__name(pushCapped, "pushCapped");
var ConnectionRegistry = class {
  constructor(onAbandonPending, onDetachSession, maxConnections = DEFAULT_MAX_CONNECTIONS, idleTtlMs = 30 * 6e4) {
    this.onAbandonPending = onAbandonPending;
    this.onDetachSession = onDetachSession;
    this.maxConnections = maxConnections;
    this.idleTtlMs = idleTtlMs;
    this.sweepTimer = setInterval(() => this.sweep(), 6e4);
    this.sweepTimer.unref();
  }
  static {
    __name(this, "ConnectionRegistry");
  }
  byId = /* @__PURE__ */ new Map();
  sweepTimer;
  /**
   * Mint a connection, or return `undefined` when the live-connection cap
   * is reached (the caller answers `503`). Bounds an `initialize` flood from
   * growing the registry without limit through the full TTL window.
   */
  create(fromLoopback) {
    if (this.maxConnections > 0 && this.byId.size >= this.maxConnections) {
      return void 0;
    }
    const conn = new AcpConnection(
      void 0,
      fromLoopback,
      this.onAbandonPending,
      this.onDetachSession
    );
    this.byId.set(conn.connectionId, conn);
    return conn;
  }
  get(connectionId) {
    if (!connectionId) return void 0;
    const conn = this.byId.get(connectionId);
    conn?.touch();
    return conn;
  }
  findPendingClientRequest(id) {
    if (id.startsWith("_qwen_perm_")) {
      const body = id.slice("_qwen_perm_".length);
      const lastUnderscore = body.lastIndexOf("_");
      if (lastUnderscore > 0) {
        const conn = this.byId.get(body.slice(0, lastUnderscore));
        const req = conn?.pending.get(id);
        if (conn && req) return { conn, id, req };
      }
    }
    for (const conn of this.byId.values()) {
      const req = conn.pending.get(id);
      if (req) return { conn, id, req };
    }
    return void 0;
  }
  /**
   * Locate a pending permission entry matching `requestId` (a bridge
   * `bridgeRequestId`, i.e. a per-request `randomUUID()`) and optionally
   * `sessionId`, returning the first match.
   *
   * NOTE: `requestId` is unique per *request*, not per *pending entry*. The
   * per-entry unique id is the `conn.pending` map key
   * (`_qwen_perm_<connectionId>_N`), which is NOT what is matched here. A
   * `permission_request` is delivered to every live subscriber of its session,
   * so when connections co-own a session (multi-client attach) each mints its
   * own entry sharing the same `bridgeRequestId`. More than one entry can
   * therefore match, so this is a *read-only locator* for deriving a session /
   * ownership from a wire `requestId`. To DELETE a resolved entry, act on the
   * specific `conn`/map-key the caller already holds (see
   * `AcpDispatcher.dropOwnPendingPermission`) — never delete by re-matching
   * here, which could hit a sibling co-owner's entry.
   */
  findPendingPermission(requestId, sessionId) {
    for (const conn of this.byId.values()) {
      for (const [id, req] of conn.pending) {
        if (req.kind === "permission" && req.bridgeRequestId === requestId && (sessionId === void 0 || req.sessionId === sessionId)) {
          return { conn, id, req };
        }
      }
    }
    return void 0;
  }
  delete(connectionId) {
    const conn = this.byId.get(connectionId);
    if (!conn) return false;
    conn.destroy();
    return this.byId.delete(connectionId);
  }
  get size() {
    return this.byId.size;
  }
  /** The configured concurrent-connection cap (for operator-facing logs). */
  get connectionCap() {
    return this.maxConnections;
  }
  getSnapshot() {
    const connections = [...this.byId.values()].map(
      (conn) => conn.getDiagnostic()
    );
    return {
      connectionCount: this.byId.size,
      connectionCap: this.maxConnections > 0 && Number.isFinite(this.maxConnections) ? this.maxConnections : null,
      connectionStreams: connections.filter((conn) => conn.connectionStreamOpen).length,
      sessionStreams: sumBy(connections, (conn) => conn.sessionStreams),
      sseStreams: sumBy(connections, (conn) => conn.sseStreams),
      wsStreams: sumBy(connections, (conn) => conn.wsStreams),
      pendingClientRequests: sumBy(
        connections,
        (conn) => conn.pendingClientRequests
      ),
      connections
    };
  }
  dispose() {
    clearInterval(this.sweepTimer);
    for (const id of [...this.byId.keys()]) this.delete(id);
  }
  sweep() {
    const cutoff = Date.now() - this.idleTtlMs;
    for (const [id, conn] of this.byId) {
      if (conn.lastActiveMs >= cutoff) continue;
      writeStderrLine(
        `qwen serve: /acp reaping idle connection ${id} (idle > ${Math.round(this.idleTtlMs / 6e4)}m, ${conn.sessions.size} session(s))`
      );
      this.delete(id);
    }
  }
};
function sumBy(values, select) {
  let total = 0;
  for (const value of values) total += select(value);
  return total;
}
__name(sumBy, "sumBy");

// packages/cli/src/serve/acp-http/sse-stream.ts
init_esbuild_shims();
var SseStream = class {
  constructor(res, onClose, onHeartbeat) {
    this.res = res;
    this.onClose = onClose;
    this.onHeartbeat = onHeartbeat;
  }
  static {
    __name(this, "SseStream");
  }
  kind = "sse";
  writeChain = Promise.resolve();
  heartbeat;
  closed = false;
  cleanupFn;
  /** Write SSE headers + retry hint and start the heartbeat. */
  open() {
    this.res.status(200);
    this.res.setHeader("Content-Type", "text/event-stream");
    this.res.setHeader("Cache-Control", "no-cache, no-transform");
    this.res.setHeader("Connection", "keep-alive");
    this.res.setHeader("X-Accel-Buffering", "no");
    this.res.flushHeaders();
    void this.writeRaw("retry: 3000\n\n");
    this.heartbeat = setInterval(() => {
      if (this.closed) return;
      this.onHeartbeat?.();
      void this.writeRaw(": hb\n\n");
    }, 15e3);
    this.heartbeat.unref();
    this.cleanupFn = () => this.close();
    this.res.req.on("close", this.cleanupFn);
    this.res.on("error", this.cleanupFn);
  }
  /**
   * Serialize a JSON-RPC message as one SSE frame. When `id` is supplied
   * (a bus event id) prepend an `id:` line so an EventSource/SSE client
   * tracks it and resends it as `Last-Event-ID` on reconnect — the resume
   * cursor for ring replay. Omitted for JSON-RPC responses and synthetic
   * terminal frames (no bus id), matching REST `formatSseFrame`.
   */
  send(message, id) {
    const idLine = id !== void 0 ? `id: ${id}
` : "";
    return this.writeRaw(`${idLine}data: ${JSON.stringify(message)}

`);
  }
  get isClosed() {
    return this.closed;
  }
  close() {
    if (this.closed) return;
    this.closed = true;
    if (this.heartbeat) clearInterval(this.heartbeat);
    if (this.cleanupFn) {
      this.res.req.off("close", this.cleanupFn);
      this.res.off("error", this.cleanupFn);
      this.cleanupFn = void 0;
    }
    try {
      if (!this.res.writableEnded) this.res.end();
    } catch {
    }
    try {
      this.onClose?.();
    } catch (err) {
      writeStderrLine(
        `qwen serve: /acp SSE onClose threw: ${err instanceof Error ? err.message : String(err)}`
      );
    }
  }
  writeRaw(chunk) {
    const next = this.writeChain.then(() => this.doWrite(chunk));
    this.writeChain = next.catch((err) => {
      if (!this.closed) {
        writeStderrLine(
          `qwen serve: /acp SSE write failed, closing stream: ${err instanceof Error ? err.message : String(err)}`
        );
        this.close();
      }
      return void 0;
    });
    return next;
  }
  doWrite(chunk) {
    return new Promise((resolve5, reject) => {
      if (this.closed || this.res.writableEnded) {
        resolve5();
        return;
      }
      let ok;
      try {
        ok = this.res.write(chunk);
      } catch (err) {
        reject(err);
        return;
      }
      if (ok) {
        resolve5();
        return;
      }
      const cleanup = /* @__PURE__ */ __name(() => {
        this.res.off("drain", onDrain);
        this.res.off("close", onCloseEv);
        this.res.off("error", onErrorEv);
      }, "cleanup");
      const onDrain = /* @__PURE__ */ __name(() => {
        cleanup();
        resolve5();
      }, "onDrain");
      const onCloseEv = /* @__PURE__ */ __name(() => {
        cleanup();
        resolve5();
      }, "onCloseEv");
      const onErrorEv = /* @__PURE__ */ __name((err) => {
        cleanup();
        reject(err);
      }, "onErrorEv");
      this.res.once("drain", onDrain);
      this.res.once("close", onCloseEv);
      this.res.once("error", onErrorEv);
    });
  }
};

// packages/cli/src/serve/acp-http/ws-stream.ts
init_esbuild_shims();
var WsStream = class {
  constructor(ws, onClose, onHeartbeat) {
    this.ws = ws;
    this.onClose = onClose;
    this.onHeartbeat = onHeartbeat;
    ws.on("close", () => this.close());
    ws.on("error", (err) => {
      writeStderrLine(
        `qwen serve: /acp WS error: ${err instanceof Error ? err.message : String(err)}`
      );
      this.close();
    });
    let alive = true;
    ws.on("pong", () => {
      alive = true;
    });
    this.heartbeat = setInterval(() => {
      if (this._closed) return;
      if (!alive) {
        this.close();
        return;
      }
      alive = false;
      try {
        this.onHeartbeat?.();
      } catch {
      }
      try {
        this.ws.ping();
      } catch {
      }
    }, 15e3);
    this.heartbeat.unref();
  }
  static {
    __name(this, "WsStream");
  }
  kind = "ws";
  writeChain = Promise.resolve();
  _closed = false;
  heartbeat;
  // `_id` (bus event id) is accepted for `TransportStream` parity but ignored:
  // WebSocket is a stateful connection with no SSE `Last-Event-ID` replay
  // (matches `AcpWsTransport.supportsReplay = false`).
  send(message, _id) {
    const data = JSON.stringify(message);
    const next = this.writeChain.then(
      () => new Promise((resolve5, reject) => {
        if (this._closed) {
          resolve5();
          return;
        }
        this.ws.send(data, (err) => {
          if (err) reject(err);
          else resolve5();
        });
      })
    );
    this.writeChain = next.catch((err) => {
      if (!this._closed) {
        writeStderrLine(
          `qwen serve: /acp WS write failed: ${err instanceof Error ? err.message : String(err)}`
        );
        this.close();
      }
    });
    return this.writeChain;
  }
  get isClosed() {
    return this._closed;
  }
  close() {
    if (this._closed) return;
    this._closed = true;
    if (this.heartbeat) clearInterval(this.heartbeat);
    try {
      if (this.ws.readyState === this.ws.OPEN) this.ws.close(1e3);
    } catch {
    }
    try {
      this.onClose?.();
    } catch (err) {
      writeStderrLine(
        `qwen serve: /acp WS onClose threw: ${err instanceof Error ? err.message : String(err)}`
      );
    }
  }
};

// packages/cli/src/serve/sse-last-event-id.ts
init_esbuild_shims();
function safeLogValue2(raw) {
  const s = typeof raw === "string" ? raw : String(raw);
  const clipped = s.length > 64 ? `${s.slice(0, 64)}\u2026` : s;
  return logSafe(clipped);
}
__name(safeLogValue2, "safeLogValue");
function parseLastEventId2(raw, logPrefix = "") {
  if (typeof raw !== "string" || !/^\d+$/.test(raw)) {
    if (typeof raw === "string" && raw.length > 0) {
      writeStderrLine(
        `qwen serve: ${logPrefix}rejected Last-Event-ID ${safeLogValue2(raw)} (not a decimal integer)`
      );
    }
    return void 0;
  }
  const n = Number.parseInt(raw, 10);
  if (!Number.isFinite(n) || n > Number.MAX_SAFE_INTEGER) {
    writeStderrLine(
      `qwen serve: ${logPrefix}rejected Last-Event-ID ${safeLogValue2(raw)} (exceeds Number.MAX_SAFE_INTEGER)`
    );
    return void 0;
  }
  return n;
}
__name(parseLastEventId2, "parseLastEventId");

// packages/cli/src/serve/acp-http/client-mcp-ws.ts
init_esbuild_shims();
var CLIENT_MCP_FRAME_TYPES = {
  register: "mcp_register",
  message: "mcp_message",
  unregister: "mcp_unregister"
};
var MAX_SERVERS_PER_CONNECTION = 10;
var ClientMcpWsConnection = class {
  constructor(sendFrame, provider) {
    this.sendFrame = sendFrame;
    this.provider = provider;
    this.registrar = new ClientMcpRegistrar({
      sendFrame: /* @__PURE__ */ __name((frame) => {
        this.sendFrame({
          type: CLIENT_MCP_FRAME_TYPES.message,
          id: frame.id,
          server: frame.server,
          payload: frame.payload
        });
      }, "sendFrame")
    });
  }
  static {
    __name(this, "ClientMcpWsConnection");
  }
  registrar;
  disposed = false;
  /**
   * Route a parsed inbound frame. Returns a structured result the WS layer can
   * turn into an ack/error reply (or ignore). Never throws — protocol errors
   * are returned as `{ kind: 'error' }`.
   */
  async handleFrame(frame) {
    if (this.disposed) {
      return { kind: "error", code: "closed", message: "connection closed" };
    }
    switch (frame.type) {
      case CLIENT_MCP_FRAME_TYPES.register:
        return this.handleRegister(frame.server);
      case CLIENT_MCP_FRAME_TYPES.unregister:
        return this.handleUnregister(frame.server);
      case CLIENT_MCP_FRAME_TYPES.message:
        return this.handleMessage(frame.id, frame.payload);
      default:
        return {
          kind: "ignored",
          reason: `unknown client-mcp frame type: ${String(frame.type)}`
        };
    }
  }
  /** Whether a frame's `type` is one this module owns. */
  static isClientMcpFrameType(type) {
    return type === CLIENT_MCP_FRAME_TYPES.register || type === CLIENT_MCP_FRAME_TYPES.message || type === CLIENT_MCP_FRAME_TYPES.unregister;
  }
  async handleRegister(server) {
    if (!isValidServerName(server)) {
      return {
        kind: "error",
        code: "invalid_server_name",
        message: "server must be \u2264256 chars, alphanumeric + underscore/hyphen, and not a reserved JS property name"
      };
    }
    if (this.registrar.hasServer(server)) {
      return {
        kind: "error",
        code: "already_registered",
        message: `server '${server}' is already registered on this connection`
      };
    }
    if (this.registrar.serverCount() >= MAX_SERVERS_PER_CONNECTION) {
      return {
        kind: "error",
        code: "too_many_servers",
        message: `connection has reached the maximum of ${MAX_SERVERS_PER_CONNECTION} registered MCP servers`
      };
    }
    if (!this.provider) {
      return {
        kind: "error",
        code: "not_wired",
        message: "client_mcp_over_ws is advertised but no McpClientManager provider is wired into this daemon process"
      };
    }
    this.registrar.registerServer(server);
    try {
      const { toolCount } = await this.provider.registerClientMcpServer(
        server,
        this.registrar.sendSdkMcpMessage
      );
      if (this.disposed) {
        this.registrar.unregisterServer(server);
        await this.provider.unregisterClientMcpServer(server);
        return {
          kind: "error",
          code: "closed",
          message: "connection disposed during register"
        };
      }
      return { kind: "registered", server, toolCount };
    } catch (err) {
      this.registrar.unregisterServer(server);
      return {
        kind: "error",
        code: "register_failed",
        message: err instanceof Error ? err.message : String(err)
      };
    }
  }
  async handleUnregister(server) {
    if (this.disposed) {
      return { kind: "unregistered", server: String(server) };
    }
    if (!isValidServerName(server)) {
      return {
        kind: "error",
        code: "invalid_server_name",
        message: "server name is invalid"
      };
    }
    const existed = this.registrar.unregisterServer(server);
    if (existed && this.provider) {
      try {
        await this.provider.unregisterClientMcpServer(server);
      } catch {
      }
    }
    return { kind: "unregistered", server };
  }
  handleMessage(id, payload) {
    if (typeof id !== "string" || id.length === 0) {
      return {
        kind: "error",
        code: "invalid_id",
        message: "`id` must be a non-empty string"
      };
    }
    if (payload === null || typeof payload !== "object") {
      return {
        kind: "error",
        code: "invalid_payload",
        message: "`payload` must be a JSON-RPC message object"
      };
    }
    const resolved = this.registrar.resolveMessage(
      id,
      payload
    );
    return resolved ? { kind: "message_resolved", id } : { kind: "ignored", reason: `no pending request for id '${id}'` };
  }
  /** Currently-registered server names on this connection. */
  registeredServers() {
    return this.registrar.registeredServers();
  }
  /** In-flight `mcp_message` round-trip count (for tests / accounting). */
  pendingCount() {
    return this.registrar.pendingCount();
  }
  /**
   * Tear the connection down: reject pending, forget servers, and best-effort
   * remove each from the provider. Idempotent.
   */
  async dispose(reason = "client MCP WS connection closed") {
    if (this.disposed) return;
    this.disposed = true;
    const servers = this.registrar.registeredServers();
    this.registrar.close(reason);
    if (this.provider) {
      await Promise.allSettled(
        servers.map(
          (server) => this.provider.unregisterClientMcpServer(server)
        )
      );
    }
  }
};

// packages/cli/src/serve/cdp-tunnel/cdp-reverse-link.ts
init_esbuild_shims();
var CDP_FRAME_TYPES = {
  /** Ask the extension to `chrome.debugger.attach` the active tab. */
  attach: "cdp_attach",
  /** Ack from the extension that the tab is attached. */
  attached: "cdp_attached",
  /** A page-domain CDP command to run on the real tab. */
  command: "cdp_command",
  /** The result (or error) of a `cdp_command`, correlated by `id`. */
  result: "cdp_result",
  /** A CDP event emitted by the real tab. */
  event: "cdp_event",
  /** The tab/debugger detached (user opened DevTools, page crashed, …). */
  detach: "cdp_detach",
  /**
   * Tell the extension to release its `chrome.debugger` attachment because the
   * `/cdp` puppeteer client went away (the extension is still connected).
   */
  release: "cdp_release"
};
var DEFAULT_COMMAND_TIMEOUT_MS = 17e4;
var COMMAND_PROGRESS_LOG_MS = 3e4;
function isCdpInboundFrameType(type) {
  return type === CDP_FRAME_TYPES.result || type === CDP_FRAME_TYPES.event || type === CDP_FRAME_TYPES.attached || type === CDP_FRAME_TYPES.detach;
}
__name(isCdpInboundFrameType, "isCdpInboundFrameType");
function isCdpInboundFrame(frame) {
  return isCdpInboundFrameType(frame.type);
}
__name(isCdpInboundFrame, "isCdpInboundFrame");
var CdpReverseLink = class {
  constructor(sendToExtension, commandTimeoutMs = DEFAULT_COMMAND_TIMEOUT_MS, log2) {
    this.sendToExtension = sendToExtension;
    this.commandTimeoutMs = commandTimeoutMs;
    this.log = log2;
  }
  static {
    __name(this, "CdpReverseLink");
  }
  emulator;
  nextId = 1;
  pending = /* @__PURE__ */ new Map();
  disposed = false;
  attached = false;
  attachPromise;
  /** Resolver for the in-flight `cdp_attach` (if any). */
  pendingAttach;
  /** Called when the extension reports the tab detached. */
  onDetach;
  /** Called when lazy `cdp_attach` fails before any page command can run. */
  onAttachFailure;
  /** Wire the emulator whose `forwardToTab` this link backs. */
  bindEmulator(emulator) {
    this.emulator = emulator;
  }
  /**
   * The {@link CdpEmulatorCallbacks.forwardToTab} implementation: send a
   * `cdp_command` to the extension and await the correlated `cdp_result`.
   */
  forwardToTab = /* @__PURE__ */ __name(async (method, params) => {
    if (this.disposed) {
      throw { code: -32e3, message: "CDP tunnel closed" };
    }
    await this.attach();
    return new Promise((resolve5, reject) => {
      if (this.disposed) {
        reject({ code: -32e3, message: "CDP tunnel closed" });
        return;
      }
      const id = this.nextId++;
      const timer = this.armTimeout(
        id,
        `CDP command id=${id} method=${method} timed out after ${this.commandTimeoutMs}ms`
      );
      const progressTimer = this.armProgressLog(id, method);
      this.pending.set(id, { resolve: resolve5, reject, timer, progressTimer });
      try {
        this.log?.(
          `qwen serve: /cdp forwarded command id=${id} method=${method} to extension`
        );
        this.sendToExtension({
          type: CDP_FRAME_TYPES.command,
          id,
          method,
          params
        });
      } catch (err) {
        this.settleReject(id, {
          code: -32e3,
          message: err instanceof Error ? err.message : String(err)
        });
      }
    });
  }, "forwardToTab");
  /**
   * Ask the extension to attach `chrome.debugger` to the active tab. Resolves
   * once the extension acks `cdp_attached` (or rejects on error/timeout).
   */
  attach() {
    if (this.attached) return Promise.resolve({});
    if (this.attachPromise) return this.attachPromise;
    this.attachPromise = new Promise(
      (resolve5, reject) => {
        if (this.disposed) {
          reject({ code: -32e3, message: "CDP tunnel closed" });
          return;
        }
        const id = this.nextId++;
        const timer = this.armTimeout(id, "cdp_attach timed out");
        this.pendingAttach = {
          id,
          pending: {
            resolve: /* @__PURE__ */ __name((result) => resolve5(result ?? {}), "resolve"),
            reject,
            timer
          }
        };
        try {
          this.sendToExtension({ type: CDP_FRAME_TYPES.attach, id });
        } catch (err) {
          clearTimeout(timer);
          this.pendingAttach = void 0;
          reject({
            code: -32e3,
            message: err instanceof Error ? err.message : String(err)
          });
        }
      }
    ).then(
      (info) => {
        this.emulator?.setTabInfo(info);
        return info;
      },
      (err) => {
        this.attached = false;
        this.onAttachFailure?.(
          err instanceof Error ? err.message : err?.message ?? String(err)
        );
        throw err;
      }
    );
    void this.attachPromise.finally(() => {
      this.attachPromise = void 0;
    }).catch(() => {
    });
    return this.attachPromise;
  }
  /**
   * Feed one inbound frame from the extension `/acp` socket. Returns true if
   * the frame was consumed by this link (so the WS layer can skip it).
   */
  handleInbound(frame) {
    if (!isCdpInboundFrame(frame)) return false;
    switch (frame.type) {
      case CDP_FRAME_TYPES.result:
        this.handleResult(frame);
        return true;
      case CDP_FRAME_TYPES.event:
        this.handleEvent(frame);
        return true;
      case CDP_FRAME_TYPES.attached:
        this.handleAttached(frame);
        return true;
      case CDP_FRAME_TYPES.detach:
        this.handleDetach(frame);
        return true;
      default:
        return false;
    }
  }
  handleResult(frame) {
    const id = typeof frame.id === "number" ? frame.id : void 0;
    if (id === void 0) {
      this.log?.("qwen serve: /cdp dropped cdp_result with non-numeric id");
      return;
    }
    if (frame.error) {
      this.settleReject(id, frame.error);
    } else {
      this.settleResolve(id, frame.result);
    }
  }
  handleEvent(frame) {
    if (!this.emulator) return;
    if (typeof frame.method !== "string") {
      this.log?.("qwen serve: /cdp dropped cdp_event with non-string method");
      return;
    }
    this.emulator.emitTabEvent(frame.method, frame.params);
  }
  handleAttached(frame) {
    const attach = this.pendingAttach;
    if (!attach || attach.id !== frame.id) {
      this.log?.(
        `qwen serve: /cdp dropped unexpected cdp_attached (id=${String(frame.id)})`
      );
      return;
    }
    this.pendingAttach = void 0;
    clearTimeout(attach.pending.timer);
    if (frame.error) {
      this.attached = false;
      attach.pending.reject({
        code: -32e3,
        message: frame.error.message ?? "cdp_attach failed"
      });
      return;
    }
    this.attached = true;
    attach.pending.resolve({ url: frame.url, title: frame.title });
  }
  handleDetach(frame) {
    const reason = typeof frame.reason === "string" ? frame.reason : "tab detached";
    this.attached = false;
    if (this.pendingAttach) {
      clearTimeout(this.pendingAttach.pending.timer);
      this.pendingAttach.pending.reject({ code: -32e3, message: reason });
      this.pendingAttach = void 0;
    }
    this.onDetach?.(reason);
  }
  armTimeout(id, message) {
    const timer = setTimeout(() => {
      this.settleReject(id, { code: -32e3, message });
      if (this.pendingAttach?.id === id) {
        this.pendingAttach.pending.reject({ code: -32e3, message });
        this.pendingAttach = void 0;
      }
    }, this.commandTimeoutMs);
    timer.unref?.();
    return timer;
  }
  armProgressLog(id, method) {
    if (!this.log) return void 0;
    const delay2 = Math.min(COMMAND_PROGRESS_LOG_MS, this.commandTimeoutMs);
    if (delay2 >= this.commandTimeoutMs) return void 0;
    const timer = setTimeout(() => {
      this.log?.(
        `qwen serve: /cdp still waiting for command id=${id} method=${method} after ${delay2}ms`
      );
    }, delay2);
    timer.unref?.();
    return timer;
  }
  settleResolve(id, result) {
    const p = this.pending.get(id);
    if (!p) return;
    clearTimeout(p.timer);
    if (p.progressTimer) clearTimeout(p.progressTimer);
    this.pending.delete(id);
    p.resolve(result);
  }
  settleReject(id, err) {
    const p = this.pending.get(id);
    if (!p) return;
    clearTimeout(p.timer);
    if (p.progressTimer) clearTimeout(p.progressTimer);
    this.pending.delete(id);
    p.reject(err);
  }
  /** In-flight forwarded-command count (for tests / accounting). */
  pendingCount() {
    return this.pending.size;
  }
  /** Reject all pending commands and stop accepting new ones. Idempotent. */
  dispose(reason = "CDP reverse link closed") {
    if (this.disposed) return;
    this.disposed = true;
    for (const [, p] of this.pending) {
      clearTimeout(p.timer);
      if (p.progressTimer) clearTimeout(p.progressTimer);
      p.reject({ code: -32e3, message: reason });
    }
    this.pending.clear();
    if (this.pendingAttach) {
      clearTimeout(this.pendingAttach.pending.timer);
      this.pendingAttach.pending.reject({ code: -32e3, message: reason });
      this.pendingAttach = void 0;
    }
    this.attached = false;
    this.attachPromise = void 0;
    this.emulator = void 0;
  }
};

// packages/cli/src/serve/cdp-tunnel/cdp-ws.ts
init_esbuild_shims();

// packages/cli/src/serve/acp-http/safe-ws-send.ts
init_esbuild_shims();
function safeWsSend(ws, payload, context = "frame") {
  if (ws.readyState === ws.OPEN) {
    try {
      ws.send(payload);
    } catch (err) {
      if (isServeDebugMode()) {
        try {
          writeStderrLine(
            `qwen serve: failed to send ${context} frame on /acp socket: ${err instanceof Error ? err.message : String(err)}`
          );
        } catch {
        }
      }
    }
    return;
  }
  if (isServeDebugMode()) {
    try {
      writeStderrLine(
        `qwen serve: dropped ${context} frame on non-OPEN /acp socket (readyState=${ws.readyState})`
      );
    } catch {
    }
  }
}
__name(safeWsSend, "safeWsSend");

// packages/cli/src/serve/cdp-tunnel/cdp-browser-emulator.ts
init_esbuild_shims();
var TAB_TARGET_ID = "qwen-cdp-tab";
var PAGE_TARGET_ID = "qwen-cdp-page";
var TAB_SESSION_ID = "qwen-cdp-tab-session";
var PAGE_SESSION_ID = "qwen-cdp-page-session";
var CDP_PROTOCOL_VERSION = "1.3";
var SERVER_ERROR = -32e3;
var CdpBrowserEmulator = class {
  constructor(cb, tab = {}) {
    this.cb = cb;
    this.tab = tab;
  }
  static {
    __name(this, "CdpBrowserEmulator");
  }
  pageSessionId = PAGE_SESSION_ID;
  /**
   * Refresh the synthetic tab/page targetInfo (url/title) once the extension
   * acks `cdp_attach`, so puppeteer's `page.url()`/`page.title()` reflect the
   * real page rather than the `about:blank` placeholder used before attach.
   */
  setTabInfo(info) {
    this.tab = { ...this.tab, ...info };
  }
  tabTargetInfo() {
    return {
      targetId: TAB_TARGET_ID,
      type: "tab",
      title: this.tab.title ?? "tab",
      url: this.tab.url ?? "about:blank",
      attached: false,
      canAccessOpener: false
    };
  }
  pageTargetInfo() {
    return {
      targetId: PAGE_TARGET_ID,
      type: "page",
      title: this.tab.title ?? "page",
      url: this.tab.url ?? "about:blank",
      attached: false,
      canAccessOpener: false
    };
  }
  /**
   * Handle one frame from the puppeteer client. Browser/tab-domain frames are
   * answered locally; page-session frames are forwarded to the real tab.
   */
  async handleFromClient(frame) {
    const { id, method, params, sessionId } = frame;
    if (!sessionId) {
      switch (method) {
        case "Browser.getVersion":
          return this.cb.reply({
            id,
            result: {
              protocolVersion: CDP_PROTOCOL_VERSION,
              product: "QwenCDPTunnel/1.0",
              revision: "@qwen",
              userAgent: "QwenCDPTunnel",
              jsVersion: "unknown"
            }
          });
        case "Target.getBrowserContexts":
          return this.cb.reply({ id, result: { browserContextIds: [] } });
        case "Target.setDiscoverTargets":
          this.cb.reply({
            method: "Target.targetCreated",
            params: { targetInfo: this.tabTargetInfo() }
          });
          this.cb.reply({
            method: "Target.targetCreated",
            params: { targetInfo: this.pageTargetInfo() }
          });
          return this.cb.reply({ id, result: {} });
        case "Target.setAutoAttach":
          this.cb.reply({
            method: "Target.attachedToTarget",
            params: {
              targetInfo: this.tabTargetInfo(),
              sessionId: TAB_SESSION_ID,
              waitingForDebugger: false
            }
          });
          return this.cb.reply({ id, result: {} });
        case "Target.getTargets":
          return this.cb.reply({
            id,
            result: {
              targetInfos: [this.tabTargetInfo(), this.pageTargetInfo()]
            }
          });
        case "Target.getTargetInfo":
          return this.cb.reply({
            id,
            result: { targetInfo: this.pageTargetInfo() }
          });
        default:
          this.cb.log?.(
            `qwen serve: /cdp unsupported browser-level CDP method: ${method ?? "(none)"}`
          );
          return this.cb.reply({ id, result: {} });
      }
    }
    if (sessionId === TAB_SESSION_ID) {
      if (method === "Target.setAutoAttach") {
        this.cb.reply({
          method: "Target.attachedToTarget",
          sessionId: TAB_SESSION_ID,
          params: {
            targetInfo: this.pageTargetInfo(),
            sessionId: PAGE_SESSION_ID,
            waitingForDebugger: false
          }
        });
        return this.cb.reply({ id, sessionId, result: {} });
      }
      return this.cb.reply({ id, sessionId, result: {} });
    }
    if (sessionId === PAGE_SESSION_ID) {
      try {
        const result = await this.cb.forwardToTab(method ?? "", params);
        return this.cb.reply({ id, sessionId, result });
      } catch (err) {
        const e = err;
        return this.cb.reply({
          id,
          sessionId,
          error: {
            code: e.code ?? SERVER_ERROR,
            message: e.message ?? "CDP forward failed",
            data: e.data
          }
        });
      }
    }
    return this.cb.reply({
      id,
      sessionId,
      error: {
        code: SERVER_ERROR,
        message: `Unknown CDP session: ${sessionId ?? "(none)"}`
      }
    });
  }
  /**
   * Re-emit a CDP event that arrived from the real tab (via the extension),
   * tagged with the page session id so puppeteer routes it to its Page.
   */
  emitTabEvent(method, params) {
    this.cb.reply({ method, params, sessionId: PAGE_SESSION_ID });
  }
};

// packages/cli/src/serve/cdp-tunnel/cdp-ws.ts
var CLOSE_NO_BRIDGE = 1011;
var CLOSE_NORMAL = 1e3;
var CDP_WS_HEARTBEAT_MS = 15e3;
function attachCdpClient(ws, registry, log2) {
  const bridge = registry.getActive();
  if (!bridge) {
    log2("qwen serve: /cdp rejected \u2014 no extension bridge connected");
    try {
      ws.close(
        CLOSE_NO_BRIDGE,
        "No browser extension connected to the CDP tunnel"
      );
    } catch {
    }
    return;
  }
  if (bridge.cdpBound) {
    log2("qwen serve: /cdp rejected \u2014 a puppeteer client is already bound");
    try {
      ws.close(CLOSE_NO_BRIDGE, "A CDP client is already connected");
    } catch {
    }
    return;
  }
  bridge.cdpBound = true;
  const link = new CdpReverseLink(
    (frame) => bridge.send(frame),
    void 0,
    log2
  );
  const emulator = new CdpBrowserEmulator({
    reply: /* @__PURE__ */ __name((frame) => {
      safeWsSend(ws, JSON.stringify(frame), "CDP");
    }, "reply"),
    forwardToTab: link.forwardToTab,
    log: log2
  });
  link.bindEmulator(emulator);
  bridge.routeInbound = (frame) => link.handleInbound(frame);
  link.onDetach = (reason) => {
    log2(`qwen serve: /cdp tab detached (${reason}); closing puppeteer socket`);
    try {
      ws.close(CLOSE_NORMAL, `tab detached: ${reason}`);
    } catch {
    }
  };
  let disposed = false;
  let heartbeatAlive = true;
  const heartbeat = setInterval(() => {
    if (disposed) return;
    if (!heartbeatAlive) {
      log2("qwen serve: /cdp heartbeat missed; closing puppeteer socket");
      dispose("puppeteer /cdp heartbeat missed");
      try {
        ws.close(CLOSE_NORMAL, "cdp heartbeat missed");
      } catch {
      }
      return;
    }
    heartbeatAlive = false;
    try {
      ws.ping();
    } catch (err) {
      log2(
        `qwen serve: /cdp heartbeat ping failed: ${err instanceof Error ? err.message : String(err)}`
      );
      dispose("puppeteer /cdp heartbeat ping failed");
      try {
        ws.close(CLOSE_NORMAL, "cdp heartbeat failed");
      } catch {
      }
    }
  }, CDP_WS_HEARTBEAT_MS);
  heartbeat.unref?.();
  const dispose = /* @__PURE__ */ __name((reason, notifyExtension = true) => {
    if (disposed) return;
    disposed = true;
    clearInterval(heartbeat);
    if (notifyExtension && registry.getActive() === bridge) {
      try {
        bridge.send({ type: CDP_FRAME_TYPES.release });
        log2(
          `qwen serve: /cdp sent release to extension (puppeteer disconnected: ${reason})`
        );
      } catch (err) {
        log2(
          `qwen serve: /cdp release send failed: ${err instanceof Error ? err.message : String(err)}`
        );
      }
    }
    link.dispose(reason);
    if (registry.getActive() === bridge) {
      bridge.routeInbound = () => false;
      bridge.cdpBound = false;
      bridge.onExtensionGone = void 0;
    }
  }, "dispose");
  link.onAttachFailure = (reason) => {
    log2(`qwen serve: /cdp attach failed (${reason}); closing puppeteer socket`);
    dispose(`cdp_attach failed: ${reason}`, false);
    try {
      ws.close(CLOSE_NO_BRIDGE, "cdp attach failed");
    } catch {
    }
  };
  ws.on("pong", () => {
    heartbeatAlive = true;
  });
  bridge.onExtensionGone = () => {
    log2("qwen serve: extension /acp dropped; closing puppeteer /cdp socket");
    dispose("extension /acp disconnected", false);
    try {
      ws.close(CLOSE_NORMAL, "extension disconnected");
    } catch {
    }
  };
  ws.on("message", (data) => {
    let frame;
    try {
      const text = typeof data === "string" ? data : data.toString("utf8");
      frame = JSON.parse(text);
    } catch {
      return;
    }
    void emulator.handleFromClient(frame).catch((err) => {
      log2(
        `qwen serve: /cdp emulator error: ${err instanceof Error ? err.message : String(err)}`
      );
    });
  });
  ws.on("close", () => dispose("puppeteer /cdp socket closed"));
  ws.on("error", (err) => {
    log2(
      `qwen serve: /cdp WS error: ${err instanceof Error ? err.message : String(err)}`
    );
    dispose("puppeteer /cdp socket error");
  });
  log2("qwen serve: /cdp puppeteer client bound to extension bridge");
}
__name(attachCdpClient, "attachCdpClient");

// packages/cli/src/serve/acp-http/index.ts
var ACP_CONNECTION_HEADER = "acp-connection-id";
var ACP_SESSION_HEADER = "acp-session-id";
var CDP_PATH = "/cdp";
function isActiveDrainCorrelation(registry, conn, message) {
  if (isResponse(message) && typeof message.id === "string") {
    const pending = registry.findPendingClientRequest(message.id);
    return pending !== void 0 && (pending.conn === conn || conn.ownsSession(pending.req.sessionId));
  }
  if (!(isRequest(message) || isNotification(message)) || message.method !== "session/cancel") {
    return false;
  }
  const params = message.params !== null && typeof message.params === "object" ? message.params : void 0;
  return typeof params?.sessionId === "string" && conn.ownsSession(params.sessionId);
}
__name(isActiveDrainCorrelation, "isActiveDrainCorrelation");
var PLURAL_WS_PREFIX = "/workspaces/";
var PLURAL_ACP_WS_SUFFIX = "/acp";
var PLURAL_VOICE_WS_SUFFIX = "/voice/stream";
function rawRequestPathname(reqUrl) {
  const target = reqUrl ?? "/";
  const qIdx = target.indexOf("?");
  const hIdx = target.indexOf("#");
  let end = target.length;
  if (qIdx >= 0) end = Math.min(end, qIdx);
  if (hIdx >= 0) end = Math.min(end, hIdx);
  return target.slice(0, end);
}
__name(rawRequestPathname, "rawRequestPathname");
function pluralWorkspaceRawSelector(rawPath, suffix) {
  let p = rawPath;
  if (p.endsWith(`${suffix}/`)) {
    p = p.slice(0, -1);
  }
  if (!p.startsWith(PLURAL_WS_PREFIX) || !p.endsWith(suffix) || p.length <= PLURAL_WS_PREFIX.length + suffix.length) {
    return null;
  }
  const selector = p.slice(PLURAL_WS_PREFIX.length, p.length - suffix.length);
  if (selector.length === 0 || selector.includes("/") || selector.includes("\\")) {
    return null;
  }
  const lower = selector.toLowerCase();
  if (lower === "." || lower === ".." || lower === "%2e" || lower === "%2e%2e" || lower === ".%2e" || lower === "%2e.") {
    return null;
  }
  return selector;
}
__name(pluralWorkspaceRawSelector, "pluralWorkspaceRawSelector");
var CDP_BRIDGE_CLIENT_NAME = "qwen-cdp-bridge";
var CHROME_DEVTOOLS_MCP_SERVER_NAME = "chrome-devtools";
var RUNTIME_MCP_RETRY_DELAY_MS = 250;
var RUNTIME_MCP_RETRY_ATTEMPTS = 20;
function formatCdpEndpointHost(hostname) {
  const host = hostname?.trim() || "127.0.0.1";
  if (host === "0.0.0.0" || host === "::" || host === "[::]") {
    return "127.0.0.1";
  }
  const unbracketed = host.startsWith("[") && host.endsWith("]") ? host.slice(1, -1) : host;
  return unbracketed.includes(":") ? `[${unbracketed}]` : unbracketed;
}
__name(formatCdpEndpointHost, "formatCdpEndpointHost");
function isAcpChannelUnavailable(err) {
  return err?.data?.errorKind === "acp_channel_unavailable";
}
__name(isAcpChannelUnavailable, "isAcpChannelUnavailable");
function delay(ms) {
  return new Promise((resolve5) => setTimeout(resolve5, ms));
}
__name(delay, "delay");
function buildChromeDevToolsMcpRuntimeConfig(localPort, hostname) {
  if (localPort === void 0 || !Number.isInteger(localPort) || localPort <= 0) {
    return void 0;
  }
  const command = resolveCdpMcpCommand(process.env);
  if (!command) {
    writeStderrLine(
      `qwen serve: set ${QWEN_CDP_MCP_COMMAND_ENV} to enable browser automation MCP (no adapter is bundled)`
    );
    return void 0;
  }
  return {
    command,
    args: [
      "--wsEndpoint",
      `ws://${formatCdpEndpointHost(hostname)}:${localPort}/cdp`
    ],
    alwaysLoadTools: true,
    [RUNTIME_MCP_IF_ABSENT_CONFIG_FLAG]: true
  };
}
__name(buildChromeDevToolsMcpRuntimeConfig, "buildChromeDevToolsMcpRuntimeConfig");
var WS_BEARER_SUBPROTOCOL_PREFIX = "qwen-bearer.";
function extractUpgradeBearer(req) {
  const authHeader = req.headers["authorization"];
  if (authHeader && authHeader.includes(" ")) {
    const scheme = authHeader.slice(0, authHeader.indexOf(" ")).toLowerCase();
    if (scheme === "bearer") {
      const credentials = authHeader.slice(authHeader.indexOf(" ") + 1).trim();
      if (credentials) return credentials;
    }
  }
  const offered = req.headers["sec-websocket-protocol"];
  if (offered) {
    for (const raw of offered.split(",")) {
      const entry = raw.trim();
      if (!entry.startsWith(WS_BEARER_SUBPROTOCOL_PREFIX)) continue;
      const encoded = entry.slice(WS_BEARER_SUBPROTOCOL_PREFIX.length);
      const decoded = Buffer.from(encoded, "base64url").toString("utf8");
      if (decoded) return decoded;
    }
  }
  return void 0;
}
__name(extractUpgradeBearer, "extractUpgradeBearer");
var CONN_GRACE_MS = 1e4;
var SESSION_GRACE_MS = 1e4;
var WS_EXEMPT_METHODS = /* @__PURE__ */ new Set([
  "_qwen/session/heartbeat",
  "_qwen/session/update_metadata"
]);
var WS_READ_METHODS = /* @__PURE__ */ new Set([
  "session/list",
  "_qwen/session/context",
  "_qwen/session/supported_commands",
  "_qwen/session/context_usage",
  "_qwen/session/tasks",
  "_qwen/session/lsp",
  "_qwen/session/artifacts",
  "_qwen/workspace/mcp",
  "_qwen/workspace/skills",
  "_qwen/workspace/providers",
  "_qwen/workspace/env",
  "_qwen/workspace/preflight",
  "_qwen/workspace/session_groups/list",
  "_qwen/workspace/trust",
  "_qwen/workspace/permissions",
  "_qwen/workspace/voice",
  "_qwen/workspace/tools",
  "_qwen/workspace/mcp/tools",
  "_qwen/workspace/mcp/resources",
  "_qwen/workspace/agents/list",
  "_qwen/workspace/agents/get",
  "_qwen/workspace/memory",
  "_qwen/workspace/memory/remember/get",
  "_qwen/workspace/memory/forget/get",
  "_qwen/workspace/memory/dream/get",
  "_qwen/workspace/auth/status",
  "_qwen/workspace/auth/device_flow/get",
  "_qwen/file/read",
  "_qwen/file/read_bytes",
  "_qwen/file/stat",
  "_qwen/file/list",
  "_qwen/file/glob"
]);
function isSameLoopbackOrigin(origin, localPort) {
  if (!localPort) return false;
  const parsed = new URL(origin);
  const allowed = /* @__PURE__ */ new Set([
    `http://localhost:${localPort}`,
    `http://127.0.0.1:${localPort}`,
    `http://[::1]:${localPort}`,
    `https://localhost:${localPort}`,
    `https://127.0.0.1:${localPort}`,
    `https://[::1]:${localPort}`
  ]);
  if (localPort === 80 || localPort === 443) {
    for (const host of ["localhost", "127.0.0.1", "[::1]"]) {
      allowed.add(`http://${host}`);
      allowed.add(`https://${host}`);
    }
  }
  return allowed.has(parsed.origin.toLowerCase());
}
__name(isSameLoopbackOrigin, "isSameLoopbackOrigin");
var MAX_INFLIGHT_MCP_DISPATCH = 8;
function workspaceRateLimitKey(mount, clientKey) {
  return JSON.stringify([clientKey, mount.rateLimitScope]);
}
__name(workspaceRateLimitKey, "workspaceRateLimitKey");
function mountAcpHttp(app, bridge, opts) {
  const enabled = opts.enabled ?? resolveAcpHttpEnabled();
  if (!enabled) return void 0;
  const path15 = opts.path ?? "/acp";
  const dispatcherRef = {};
  let disposed = false;
  const rejectIfDisposed = /* @__PURE__ */ __name((res) => {
    if (!disposed) return false;
    res.status(503).json({
      error: "ACP HTTP transport has been disposed",
      code: "server_disposed"
    });
    return true;
  }, "rejectIfDisposed");
  const rejectIfUnavailable = /* @__PURE__ */ __name((mount, res) => {
    if (rejectIfDisposed(res)) return true;
    if (!mount.draining) return false;
    res.set("Retry-After", "5");
    res.status(503).json({
      error: "Workspace runtime is being removed",
      code: "workspace_draining",
      workspaceCwd: mount.workspaceCwd
    });
    return true;
  }, "rejectIfUnavailable");
  const registry = new ConnectionRegistry(
    (req, clientId) => {
      if (!dispatcherRef.current) {
        writeStderrLine(
          "qwen serve: /acp abandonPending called before dispatcher initialized (skipped)"
        );
        return false;
      }
      return dispatcherRef.current.cancelAbandonedPermission(req, clientId);
    },
    // Best-effort bridge detach so a torn-down connection's bridge-stamped
    // client ids don't linger in the bridge's voter/known-client sets.
    (sessionId, clientId) => {
      void bridge.detachClient(sessionId, clientId).catch((err) => {
        writeStderrLine(
          `qwen serve: /acp detachClient(${sessionId}) failed: ${err instanceof Error ? err.message : String(err)}`
        );
      });
    },
    opts.maxConnections
  );
  let cdpMcpRegistered = false;
  let cdpMcpRegistering;
  let cdpMcpTerminalSkipLogged = false;
  async function removeChromeDevToolsMcp(originatorClientId) {
    if (!cdpMcpRegistered) return;
    cdpMcpRegistered = false;
    try {
      await bridge.removeRuntimeMcpServer(
        CHROME_DEVTOOLS_MCP_SERVER_NAME,
        originatorClientId
      );
    } catch (err) {
      writeStderrLine(
        `qwen serve: failed to remove ${CHROME_DEVTOOLS_MCP_SERVER_NAME} runtime MCP: ${err instanceof Error ? err.message : String(err)}`
      );
    }
  }
  __name(removeChromeDevToolsMcp, "removeChromeDevToolsMcp");
  function removeChromeDevToolsMcpIfUnused(originatorClientId) {
    void (async () => {
      if (opts.cdpTunnelRegistry?.hasActive()) return;
      if (cdpMcpRegistering) await cdpMcpRegistering;
      if (opts.cdpTunnelRegistry?.hasActive()) return;
      await removeChromeDevToolsMcp(originatorClientId);
    })().catch((err) => {
      writeStderrLine(
        `qwen serve: failed to clean up ${CHROME_DEVTOOLS_MCP_SERVER_NAME} runtime MCP: ${err instanceof Error ? err.message : String(err)}`
      );
    });
  }
  __name(removeChromeDevToolsMcpIfUnused, "removeChromeDevToolsMcpIfUnused");
  function ensureChromeDevToolsMcpRegistered(localPort, originatorClientId) {
    if (opts.token) {
      if (!cdpMcpTerminalSkipLogged) {
        writeStderrLine(
          `qwen serve: ${CHROME_DEVTOOLS_MCP_SERVER_NAME} runtime MCP skipped because /cdp requires bearer auth`
        );
        cdpMcpTerminalSkipLogged = true;
      }
      return;
    }
    if (cdpMcpRegistered || cdpMcpRegistering || cdpMcpTerminalSkipLogged) {
      return;
    }
    const runtimeConfig = buildChromeDevToolsMcpRuntimeConfig(
      localPort,
      opts.hostname
    );
    if (!runtimeConfig) {
      cdpMcpTerminalSkipLogged = true;
      return;
    }
    cdpMcpRegistering = (async () => {
      try {
        let result;
        for (let attempt = 0; ; attempt++) {
          try {
            result = await bridge.addRuntimeMcpServer(
              CHROME_DEVTOOLS_MCP_SERVER_NAME,
              runtimeConfig,
              originatorClientId
            );
            break;
          } catch (err) {
            if (!isAcpChannelUnavailable(err) || attempt >= RUNTIME_MCP_RETRY_ATTEMPTS || !opts.cdpTunnelRegistry?.hasActive()) {
              throw err;
            }
            await delay(RUNTIME_MCP_RETRY_DELAY_MS);
          }
        }
        if (result.skipped) {
          writeStderrLine(
            `qwen serve: ${CHROME_DEVTOOLS_MCP_SERVER_NAME} runtime MCP skipped: ${result.reason ?? "unknown"}`
          );
          return;
        }
        if (result.shadowedSettings) {
          await bridge.removeRuntimeMcpServer(
            CHROME_DEVTOOLS_MCP_SERVER_NAME,
            originatorClientId
          ).catch(() => {
          });
          cdpMcpTerminalSkipLogged = true;
          writeStderrLine(
            `qwen serve: ${CHROME_DEVTOOLS_MCP_SERVER_NAME} runtime MCP skipped because settings already define it`
          );
          return;
        }
        cdpMcpRegistered = true;
        if (!opts.cdpTunnelRegistry?.hasActive()) {
          await removeChromeDevToolsMcp(originatorClientId);
        }
      } catch (err) {
        writeStderrLine(
          `qwen serve: failed to add ${CHROME_DEVTOOLS_MCP_SERVER_NAME} runtime MCP: ${err instanceof Error ? err.message : String(err)}`
        );
      } finally {
        cdpMcpRegistering = void 0;
      }
    })();
  }
  __name(ensureChromeDevToolsMcpRegistered, "ensureChromeDevToolsMcpRegistered");
  const dispatcher = new AcpDispatcher(
    bridge,
    opts.boundWorkspace,
    opts.workspace,
    opts.workspaceRememberLane,
    opts.fsFactory,
    opts.deviceFlowRegistry,
    opts.sessionShellCommandEnabled === true,
    registry,
    opts.archiveCoordinator ?? new SessionArchiveCoordinator()
  );
  dispatcherRef.current = dispatcher;
  const primaryMount = {
    primary: true,
    workspaceCwd: opts.boundWorkspace,
    routeLabel: logSafe(path15),
    rateLimitScope: opts.workspaceRegistry?.primary.workspaceId ?? "primary",
    registry,
    dispatcher,
    workspaceRememberLane: opts.workspaceRememberLane,
    webSockets: /* @__PURE__ */ new Set(),
    pendingWebSockets: /* @__PURE__ */ new Set(),
    draining: false,
    ensureChromeDevToolsMcpRegistered,
    removeChromeDevToolsMcpIfUnused,
    clientMcpProviderFactory: opts.clientMcpProviderFactory
  };
  const handleAcpDelete = /* @__PURE__ */ __name((mount, req, res) => {
    if (rejectIfUnavailable(mount, res)) return;
    const connectionId = headerOf(req, ACP_CONNECTION_HEADER);
    if (!connectionId) {
      res.status(400).json({ error: "Missing Acp-Connection-Id" });
      return;
    }
    const existed = mount.registry.delete(connectionId);
    if (existed) {
      writeStderrLine(
        `qwen serve: ${mount.routeLabel} connection deleted ${connectionId.slice(0, 8)} (remaining=${mount.registry.size})`
      );
    }
    res.status(202).end();
  }, "handleAcpDelete");
  const handleAcpPost = /* @__PURE__ */ __name(async (mount, req, res) => {
    if (rejectIfDisposed(res)) return;
    const ct = req.headers["content-type"];
    if (!ct || !ct.startsWith("application/json")) {
      res.status(415).json({ error: "Content-Type must be application/json" });
      return;
    }
    if (Array.isArray(req.body)) {
      res.status(501).json({ error: "Batch JSON-RPC requests are not supported" });
      return;
    }
    const parsed = parseInbound(req.body);
    if (!parsed.ok) {
      writeStderrLine(
        `qwen serve: ${mount.routeLabel} malformed request from ${req.socket?.remoteAddress}: ${parsed.error.error.message}`
      );
      res.status(400).json(parsed.error);
      return;
    }
    const message = parsed.message;
    const cleanupMessage = (isRequest(message) || isNotification(message)) && message.method === "session/cancel";
    if (mount.draining && !isResponse(message) && !cleanupMessage) {
      res.set("Retry-After", "5");
      res.status(503).json({
        error: "Workspace runtime is being removed",
        code: "workspace_draining",
        workspaceCwd: mount.workspaceCwd
      });
      return;
    }
    if (isRequest(message) && message.method === "initialize") {
      const conn2 = mount.registry.create(isLoopbackReq(req));
      if (!conn2) {
        writeStderrLine(
          `qwen serve: ${mount.routeLabel} connection cap reached (max=${mount.registry.connectionCap}), rejecting initialize`
        );
        res.setHeader("Retry-After", "5");
        res.status(503).json(
          error(
            message.id,
            RPC.INTERNAL_ERROR,
            "Too many ACP connections; retry later"
          )
        );
        return;
      }
      const requestedVersion = message.params && typeof message.params === "object" && !Array.isArray(message.params) ? message.params["protocolVersion"] : void 0;
      res.setHeader("Acp-Connection-Id", conn2.connectionId);
      res.status(200).json({
        // success envelope: clients correlate by the request id.
        jsonrpc: "2.0",
        id: message.id,
        result: mount.dispatcher.buildInitializeResult(
          conn2.connectionId,
          requestedVersion
        )
      });
      writeStderrLine(
        `qwen serve: ${mount.routeLabel} connection established ${conn2.connectionId.slice(0, 8)} (loopback=${conn2.fromLoopback}, active=${mount.registry.size})`
      );
      return;
    }
    const connHeader = headerOf(req, ACP_CONNECTION_HEADER);
    if (!connHeader) {
      res.status(400).json(
        error(
          isRequest(message) ? message.id : null,
          RPC.INVALID_REQUEST,
          "Missing Acp-Connection-Id"
        )
      );
      return;
    }
    const conn = mount.registry.get(connHeader);
    if (!conn) {
      res.status(404).json(
        error(
          isRequest(message) ? message.id : null,
          RPC.INVALID_REQUEST,
          "Unknown Acp-Connection-Id"
        )
      );
      return;
    }
    if (mount.draining) {
      if (!isActiveDrainCorrelation(mount.registry, conn, message)) {
        res.set("Retry-After", "5");
        res.status(503).json({
          error: "Workspace runtime is being removed",
          code: "workspace_draining",
          workspaceCwd: mount.workspaceCwd
        });
        return;
      }
    }
    if (opts.checkRate && isRequest(message)) {
      const m = message.method;
      if (!WS_EXEMPT_METHODS.has(m)) {
        const tier = m === "session/prompt" || m === "_qwen/session/prompt" ? "prompt" : WS_READ_METHODS.has(m) ? "read" : "mutation";
        const httpKey = (req.socket?.remoteAddress ?? "http-unknown").replace(
          /^::ffff:/,
          ""
        );
        if (!opts.checkRate(workspaceRateLimitKey(mount, httpKey), tier)) {
          res.setHeader("Retry-After", "5");
          res.status(429).json({
            error: "Rate limit exceeded",
            code: "rate_limit_exceeded",
            tier
          });
          return;
        }
      }
    }
    res.status(202).end();
    await mount.dispatcher.handle(
      conn,
      message,
      headerOf(req, ACP_SESSION_HEADER),
      isLoopbackReq(req)
    ).catch((err) => {
      writeStderrLine(
        `qwen serve: ${mount.routeLabel} handle error: ${err instanceof Error ? err.message : String(err)}`
      );
    });
  }, "handleAcpPost");
  app.post(
    path15,
    (req, res) => handleAcpPost(primaryMount, req, res)
  );
  const handleAcpGet = /* @__PURE__ */ __name((mount, req, res) => {
    if (rejectIfUnavailable(mount, res)) return;
    const accept = req.headers["accept"] ?? "";
    if (!accept.includes("text/event-stream")) {
      res.status(406).json({ error: "Accept header must include text/event-stream" });
      return;
    }
    const connHeader = headerOf(req, ACP_CONNECTION_HEADER);
    if (!connHeader) {
      res.status(400).json({ error: "Missing Acp-Connection-Id" });
      return;
    }
    const conn = mount.registry.get(connHeader);
    if (!conn) {
      res.status(404).json({ error: "Unknown Acp-Connection-Id" });
      return;
    }
    const sessionId = headerOf(req, ACP_SESSION_HEADER);
    if (!sessionId) {
      const connId = conn.connectionId;
      const stream2 = new SseStream(
        res,
        () => {
          writeStderrLine(
            `qwen serve: ${mount.routeLabel} connection stream closed (${connId.slice(0, 8)})`
          );
          conn.clearGraceTimer();
          const reapConnIfDead = /* @__PURE__ */ __name(() => {
            if (mount.registry.get(connId) === conn && conn.connStream === stream2 && conn.connGraceExpired && !conn.hasLiveSessionStream() && !conn.hasRecoverableSession()) {
              writeStderrLine(
                `qwen serve: ${mount.routeLabel} reaping connection ${connId.slice(0, 8)} (conn stream gone, no live session stream)`
              );
              mount.registry.delete(connId);
            }
          }, "reapConnIfDead");
          conn.connGraceTimer = setTimeout(() => {
            conn.connGraceExpired = true;
            reapConnIfDead();
          }, CONN_GRACE_MS);
          conn.connGraceTimer.unref?.();
          conn.onSessionGraceExpired = reapConnIfDead;
        },
        () => conn.touch()
      );
      stream2.open();
      conn.attachConnStream(stream2);
      return;
    }
    if (!conn.ownsSession(sessionId)) {
      res.status(403).json({ error: "Session not owned by this connection" });
      return;
    }
    const ac = new AbortController();
    const stream = new SseStream(
      res,
      () => {
        ac.abort();
      },
      () => conn.touch()
    );
    stream.open();
    const lastEventId = parseLastEventId2(
      headerOf(req, "last-event-id"),
      "/acp "
    );
    conn.attachSessionStream(sessionId, stream, ac, lastEventId);
    const onPumpSettled = /* @__PURE__ */ __name(() => {
      if (stream.isClosed) {
        conn.detachSessionStream(sessionId, stream, SESSION_GRACE_MS);
      } else if (conn.sessions.get(sessionId)?.stream === stream) {
        writeStderrLine(
          `qwen serve: ${mount.routeLabel} session stream pump ended while open (${logSafe(sessionId)}) \u2014 closing`
        );
        conn.closeSessionStream(sessionId);
      } else {
        writeStderrLine(
          `qwen serve: ${mount.routeLabel} session stream pump settled for a superseded stream (${logSafe(sessionId)}) \u2014 no-op`
        );
      }
    }, "onPumpSettled");
    void mount.dispatcher.pumpSessionEvents(conn, sessionId, ac.signal, lastEventId).then(onPumpSettled, (err) => {
      writeStderrLine(
        `qwen serve: ${mount.routeLabel} event pump error (${logSafe(sessionId)}, lastEventId=${lastEventId ?? "none"}): ${logSafe(err instanceof Error ? err.message : String(err))}`
      );
      onPumpSettled();
    });
  }, "handleAcpGet");
  app.get(path15, (req, res) => {
    handleAcpGet(primaryMount, req, res);
  });
  app.delete(path15, (req, res) => {
    handleAcpDelete(primaryMount, req, res);
  });
  const createSecondaryAcpMount = /* @__PURE__ */ __name((rt) => {
    const secondaryDispatcherRef = {};
    const secondaryRegistry = new ConnectionRegistry(
      (req, clientId) => {
        if (!secondaryDispatcherRef.current) return false;
        return secondaryDispatcherRef.current.cancelAbandonedPermission(
          req,
          clientId
        );
      },
      (sessionId, clientId) => {
        void rt.bridge.detachClient(sessionId, clientId).catch((err) => {
          writeStderrLine(
            `qwen serve: /workspaces/${rt.workspaceId}/acp detachClient(${sessionId}) failed: ${err instanceof Error ? err.message : String(err)}`
          );
        });
      },
      opts.maxConnections
    );
    const workspaceRememberLane = new WorkspaceRememberTaskLane(
      rt.bridge,
      rt.workspaceCwd
    );
    const secondaryDispatcher = new AcpDispatcher(
      rt.bridge,
      rt.workspaceCwd,
      rt.workspaceService,
      workspaceRememberLane,
      rt.routeFileSystemFactory,
      // Phase 4: secondary mounts share the daemon-global device-flow registry
      // (single instance per daemon; OAuth credentials are global state). The
      // registry's event sink fans out to each trusted bridge, so a secondary
      // ACP client's device_flow calls resolve against a real registry and its
      // events reach that workspace's bridge -- without a per-runtime registry.
      opts.deviceFlowRegistry,
      opts.sessionShellCommandEnabled === true,
      secondaryRegistry,
      opts.archiveCoordinator ?? new SessionArchiveCoordinator()
    );
    secondaryDispatcherRef.current = secondaryDispatcher;
    return {
      primary: false,
      workspaceCwd: rt.workspaceCwd,
      routeLabel: `/workspaces/${logSafe(rt.workspaceId)}/acp`,
      rateLimitScope: rt.workspaceId,
      registry: secondaryRegistry,
      dispatcher: secondaryDispatcher,
      workspaceRememberLane,
      webSockets: /* @__PURE__ */ new Set(),
      pendingWebSockets: /* @__PURE__ */ new Set(),
      draining: false,
      ensureChromeDevToolsMcpRegistered: /* @__PURE__ */ __name(() => {
      }, "ensureChromeDevToolsMcpRegistered"),
      removeChromeDevToolsMcpIfUnused: /* @__PURE__ */ __name(() => {
      }, "removeChromeDevToolsMcpIfUnused"),
      // Reverse client-MCP over WS is per-runtime: a connection on this
      // workspace's ACP registers client-hosted MCP servers in this runtime's
      // sender registry + bridge only. Only wired when the reverse channel is
      // enabled (mirrors the primary mount).
      clientMcpProviderFactory: opts.clientMcpOverWs === true ? (connectionId) => createClientMcpServerProvider(
        rt.clientMcpSenderRegistry,
        rt.bridge,
        connectionId
      ) : void 0
    };
  }, "createSecondaryAcpMount");
  const secondaryMounts = /* @__PURE__ */ new Map();
  const drainingWorkspaceIds = /* @__PURE__ */ new Set();
  const getOrCreateSecondaryMount = /* @__PURE__ */ __name((rt) => {
    if (rt.primary || !rt.trusted) return void 0;
    const existing = secondaryMounts.get(rt.workspaceId);
    if (existing) return existing;
    const mount = createSecondaryAcpMount(rt);
    if (drainingWorkspaceIds.has(rt.workspaceId)) {
      mount.draining = true;
      mount.workspaceRememberLane.beginDrain();
    }
    secondaryMounts.set(rt.workspaceId, mount);
    return mount;
  }, "getOrCreateSecondaryMount");
  for (const rt of opts.workspaceRegistry?.list() ?? []) {
    if (!rt.primary && rt.trusted) {
      getOrCreateSecondaryMount(rt);
    }
  }
  const resolvePluralMount = /* @__PURE__ */ __name((req, res) => {
    const workspaceRegistry = opts.workspaceRegistry;
    if (!workspaceRegistry) {
      res.status(400).json({
        error: "Workspace-qualified ACP is not enabled on this daemon",
        code: "workspace_mismatch"
      });
      return null;
    }
    const rt = resolveManagedWorkspaceRuntimeFromParam(
      workspaceRegistry,
      req,
      res
    );
    if (!rt) return null;
    if (!rt.primary && !rt.trusted) {
      res.status(403).json({
        error: `Workspace "${rt.workspaceCwd}" is not trusted.`,
        code: "untrusted_workspace",
        workspaceCwd: rt.workspaceCwd,
        workspaceId: rt.workspaceId
      });
      return null;
    }
    if (rt.primary) return primaryMount;
    const mount = getOrCreateSecondaryMount(rt);
    if (!mount) {
      res.status(400).json({
        error: `Workspace "${rt.workspaceCwd}" has no registered ACP mount`,
        code: "workspace_mismatch",
        workspaceCwd: rt.workspaceCwd,
        workspaceId: rt.workspaceId
      });
      return null;
    }
    return mount;
  }, "resolvePluralMount");
  const workspaceQualifiedAcpEnabled = opts.workspaceRegistry !== void 0;
  const pluralAcpPath = "/workspaces/:workspace/acp";
  if (workspaceQualifiedAcpEnabled) {
    app.post(pluralAcpPath, (req, res) => {
      const mount = resolvePluralMount(req, res);
      if (!mount) return;
      return handleAcpPost(mount, req, res);
    });
    app.get(pluralAcpPath, (req, res) => {
      const mount = resolvePluralMount(req, res);
      if (!mount) return;
      handleAcpGet(mount, req, res);
    });
    app.delete(pluralAcpPath, (req, res) => {
      const mount = resolvePluralMount(req, res);
      if (!mount) return;
      handleAcpDelete(mount, req, res);
    });
  }
  let wss;
  let upgradeListener;
  let upgradeServer;
  function setupWebSocket(httpServer) {
    if (disposed || wss) return;
    wss = new import_websocket_server.default({
      noServer: true,
      maxPayload: 10 * 1024 * 1024,
      // Browsers authenticate the upgrade by offering the bearer token as a
      // `qwen-bearer.*` subprotocol (see extractUpgradeBearer). Never echo that
      // secret-bearing value back in the handshake response — select the first
      // non-secret subprotocol instead. The web-shell offers a non-secret
      // marker (`qwen-ws`) alongside the bearer one precisely so there is always
      // a safe value to select: selecting none would make strict WS clients
      // (e.g. the `ws` library) reject the handshake with "Server sent no
      // subprotocol". ACP clients offer no subprotocol, so this is a no-op for
      // them.
      handleProtocols: /* @__PURE__ */ __name((protocols) => {
        for (const proto of protocols) {
          if (!proto.startsWith(WS_BEARER_SUBPROTOCOL_PREFIX)) return proto;
        }
        return false;
      }, "handleProtocols")
    });
    upgradeServer = httpServer;
    const expectedTokenHash = opts.token ? createHash3("sha256").update(opts.token).digest() : void 0;
    upgradeListener = /* @__PURE__ */ __name((req, socket, head) => {
      if (disposed) {
        socket.destroy();
        return;
      }
      const rawAddr = socket.remoteAddress ?? "ws-unknown";
      const localPort = socket.localPort;
      const logReject = /* @__PURE__ */ __name((reason) => {
        writeStderrLine(
          `qwen serve: WebSocket upgrade rejected (${reason}) from ${rawAddr}`
        );
      }, "logReject");
      const rawPath = rawRequestPathname(req.url);
      const isCdpPath = opts.cdpTunnelOverWs === true && opts.cdpTunnelRegistry !== void 0 && rawPath === CDP_PATH;
      const extraRoute = opts.extraWsRoutes?.find(
        (route) => route.path === rawPath
      );
      const pluralRawSelector = workspaceQualifiedAcpEnabled ? pluralWorkspaceRawSelector(rawPath, PLURAL_ACP_WS_SUFFIX) : null;
      const isPluralAcpShape = pluralRawSelector !== null;
      const pluralVoiceRawSelector = opts.workspaceVoiceConnection ? pluralWorkspaceRawSelector(rawPath, PLURAL_VOICE_WS_SUFFIX) : null;
      const isPluralVoiceShape = pluralVoiceRawSelector !== null;
      if (rawPath !== path15 && !isCdpPath && !extraRoute && !isPluralAcpShape && !isPluralVoiceShape) {
        logReject(`unknown-path ${logSafe(rawPath)}`);
        socket.destroy();
        return;
      }
      const fromLoopback = isLoopbackSocket(socket);
      if (fromLoopback) {
        const host = (req.headers["host"] ?? "").toLowerCase();
        const allowed = /* @__PURE__ */ new Set([
          `localhost:${localPort}`,
          `127.0.0.1:${localPort}`,
          `[::1]:${localPort}`,
          `host.docker.internal:${localPort}`
        ]);
        if (localPort === 80 || localPort === 443) {
          allowed.add("localhost");
          allowed.add("127.0.0.1");
          allowed.add("[::1]");
          allowed.add("host.docker.internal");
        }
        if (!allowed.has(host)) {
          logReject(`host-not-allowed ${host || "(missing)"}`);
          socket.write("HTTP/1.1 403 Forbidden\r\n\r\n");
          socket.destroy();
          return;
        }
      }
      const origin = req.headers["origin"];
      if (origin) {
        try {
          const isLoopbackOrigin = isSameLoopbackOrigin(origin, localPort);
          const isAllowlistedOrigin = opts.allowedOrigins !== void 0 && opts.allowedOrigins.origins.has(origin.toLowerCase());
          if (!isLoopbackOrigin && !isAllowlistedOrigin) {
            logReject(`origin-not-allowed ${origin}`);
            socket.write("HTTP/1.1 403 Forbidden\r\n\r\n");
            socket.destroy();
            return;
          }
        } catch {
          logReject("invalid-origin");
          socket.write("HTTP/1.1 403 Forbidden\r\n\r\n");
          socket.destroy();
          return;
        }
      }
      if (opts.token) {
        const credentials = extractUpgradeBearer(req);
        const actual = credentials ? createHash3("sha256").update(credentials).digest() : void 0;
        if (!actual || !expectedTokenHash || actual.length !== expectedTokenHash.length || !timingSafeEqual(expectedTokenHash, actual)) {
          logReject("auth-mismatch");
          socket.write("HTTP/1.1 401 Unauthorized\r\n\r\n");
          socket.destroy();
          return;
        }
      } else if (!fromLoopback) {
        logReject("non-loopback-without-token");
        socket.write("HTTP/1.1 403 Forbidden\r\n\r\n");
        socket.destroy();
        return;
      }
      if (isCdpPath) {
        wss.handleUpgrade(req, socket, head, (ws) => {
          if (disposed) {
            ws.close(1012, "Server shutting down");
            return;
          }
          attachCdpClient(ws, opts.cdpTunnelRegistry, writeStderrLine);
        });
        return;
      }
      if (isPluralVoiceShape) {
        let selector;
        try {
          selector = decodeURIComponent(pluralVoiceRawSelector);
        } catch {
          logReject("workspace-selector-decode-error");
          socket.write("HTTP/1.1 400 Bad Request\r\n\r\n");
          socket.destroy();
          return;
        }
        const wsRegistry = opts.workspaceRegistry;
        const runtime = wsRegistry ? wsRegistry.getManagedByWorkspaceId(selector) ?? (isPortableAbsolutePath(selector) ? resolveManagedWorkspaceRuntimeByPathSelector(
          wsRegistry,
          selector
        ) : void 0) : void 0;
        if (!runtime) {
          logReject(`workspace-mismatch ${logSafe(selector)}`);
          socket.write("HTTP/1.1 400 Bad Request\r\n\r\n");
          socket.destroy();
          return;
        }
        if (!runtime.trusted) {
          logReject(`untrusted-workspace ${runtime.workspaceId}`);
          socket.write("HTTP/1.1 403 Forbidden\r\n\r\n");
          socket.destroy();
          return;
        }
        wss.handleUpgrade(req, socket, head, (ws) => {
          if (disposed) {
            ws.close(1012, "Server shutting down");
            return;
          }
          opts.workspaceVoiceConnection(runtime, ws, req);
        });
        return;
      }
      let activeMount = primaryMount;
      if (isPluralAcpShape) {
        let selector;
        try {
          selector = decodeURIComponent(pluralRawSelector);
        } catch {
          logReject("workspace-selector-decode-error");
          socket.write("HTTP/1.1 400 Bad Request\r\n\r\n");
          socket.destroy();
          return;
        }
        const wsRegistry = opts.workspaceRegistry;
        const rt = wsRegistry ? wsRegistry.getManagedByWorkspaceId(selector) ?? (isPortableAbsolutePath(selector) ? resolveManagedWorkspaceRuntimeByPathSelector(
          wsRegistry,
          selector
        ) : void 0) : void 0;
        if (!rt) {
          logReject(`workspace-mismatch ${logSafe(selector)}`);
          socket.write("HTTP/1.1 400 Bad Request\r\n\r\n");
          socket.destroy();
          return;
        }
        if (!rt.primary && !rt.trusted) {
          logReject(`untrusted-workspace ${rt.workspaceId}`);
          socket.write("HTTP/1.1 403 Forbidden\r\n\r\n");
          socket.destroy();
          return;
        }
        const resolvedMount = rt.primary ? primaryMount : getOrCreateSecondaryMount(rt);
        if (!resolvedMount) {
          logReject(`workspace-acp-no-mount ${rt.workspaceId}`);
          socket.write("HTTP/1.1 400 Bad Request\r\n\r\n");
          socket.destroy();
          return;
        }
        activeMount = resolvedMount;
      }
      if (activeMount.draining) {
        logReject(`workspace-draining ${activeMount.routeLabel}`);
        socket.write(
          "HTTP/1.1 503 Service Unavailable\r\nRetry-After: 5\r\n\r\n"
        );
        socket.destroy();
        return;
      }
      wss.handleUpgrade(req, socket, head, (ws) => {
        if (disposed) {
          ws.close(1012, "Server shutting down");
          return;
        }
        if (extraRoute) {
          extraRoute.onConnection(ws, req);
          return;
        }
        activeMount.webSockets.add(ws);
        activeMount.pendingWebSockets.add(ws);
        let initialized = false;
        const initTimer = setTimeout(() => {
          if (!initialized) {
            writeStderrLine(
              `qwen serve: ${activeMount.routeLabel} WS initialize timeout (30s) from ${rawAddr}`
            );
            ws.close(1002, "Initialize timeout");
          }
        }, 3e4);
        initTimer.unref?.();
        let connRef;
        let messageQueue = Promise.resolve();
        let clientMcp;
        let clientMcpInflightDispatch = 0;
        let cdpBridgeUnregister;
        let cdpEndpoint;
        const wsKey = rawAddr.startsWith("::ffff:") ? rawAddr.slice(7) : rawAddr;
        ws.on("error", (err) => {
          writeStderrLine(
            `qwen serve: ${activeMount.routeLabel} WS error: ${err instanceof Error ? err.message : String(err)}`
          );
        });
        ws.on("close", () => {
          clearTimeout(initTimer);
          activeMount.webSockets.delete(ws);
          activeMount.pendingWebSockets.delete(ws);
          if (clientMcp) {
            void clientMcp.dispose("WS closed").catch(() => {
            });
            clientMcp = void 0;
          }
          if (cdpBridgeUnregister) {
            cdpBridgeUnregister();
            cdpBridgeUnregister = void 0;
            activeMount.removeChromeDevToolsMcpIfUnused(
              connRef?.connectionId ?? "cdp-bridge"
            );
          }
        });
        ws.on("message", (rawData) => {
          messageQueue = messageQueue.then(() => handleWsMessage(rawData)).catch((err) => {
            writeStderrLine(
              `qwen serve: ${activeMount.routeLabel} WS message handler error: ${err instanceof Error ? err.message : String(err)}`
            );
          });
        });
        async function handleWsMessage(rawData) {
          if (disposed) {
            ws.close(1012, "Server shutting down");
            return;
          }
          let text;
          try {
            text = typeof rawData === "string" ? rawData : rawData.toString("utf8");
          } catch {
            ws.close(1003, "Only text frames supported");
            return;
          }
          let parsed;
          try {
            parsed = JSON.parse(text);
          } catch {
            ws.send(
              JSON.stringify(error(null, RPC.PARSE_ERROR, "Parse error"))
            );
            return;
          }
          if (Array.isArray(parsed)) {
            ws.send(
              JSON.stringify({
                error: "Batch JSON-RPC not supported"
              })
            );
            return;
          }
          const frameType = parsed !== null && typeof parsed === "object" ? parsed.type : void 0;
          if (activeMount.draining && frameType === "mcp_message" && clientMcp !== void 0 && parsed !== null && typeof parsed === "object") {
            const result = await clientMcp.handleFrame(
              parsed
            );
            if (result.kind === "message_resolved") return;
          }
          if (activeMount.draining && !(connRef !== void 0 && (isResponse(parsed) || isRequest(parsed) || isNotification(parsed)) && isActiveDrainCorrelation(activeMount.registry, connRef, parsed))) {
            if (opts.cdpTunnelOverWs === true && cdpEndpoint !== void 0 && parsed !== null && typeof parsed === "object" && isCdpInboundFrameType(frameType) && cdpEndpoint.routeInbound(parsed)) {
              return;
            }
            ws.send(
              JSON.stringify(
                error(
                  isRequest(parsed) ? parsed.id : null,
                  RPC.INTERNAL_ERROR,
                  "Workspace runtime is being removed",
                  {
                    code: "workspace_draining",
                    workspaceCwd: activeMount.workspaceCwd
                  }
                )
              )
            );
            return;
          }
          if (opts.clientMcpOverWs === true && parsed !== null && typeof parsed === "object" && ClientMcpWsConnection.isClientMcpFrameType(
            parsed.type
          )) {
            if (!initialized) {
              ws.send(
                JSON.stringify({
                  type: "mcp_error",
                  code: "not_initialized",
                  message: "initialize the ACP connection before mcp_register"
                })
              );
              return;
            }
            const frameType2 = parsed.type;
            if (opts.checkRate) {
              const tier = frameType2 === "mcp_message" ? "read" : "mutation";
              if (!opts.checkRate(workspaceRateLimitKey(activeMount, wsKey), tier)) {
                safeWsSend(
                  ws,
                  JSON.stringify({
                    type: "mcp_error",
                    code: "rate_limited",
                    message: "Rate limit exceeded"
                  }),
                  "client-MCP"
                );
                return;
              }
            }
            if (!clientMcp) {
              const provider = activeMount.clientMcpProviderFactory ? activeMount.clientMcpProviderFactory(
                connRef?.connectionId ?? "ws-unknown"
              ) : opts.clientMcpProvider;
              clientMcp = new ClientMcpWsConnection(
                (frame) => safeWsSend(ws, JSON.stringify(frame), "client-MCP"),
                provider
              );
            }
            const sendClientMcpAck = /* @__PURE__ */ __name((result) => {
              if (result.kind === "registered") {
                safeWsSend(
                  ws,
                  JSON.stringify({
                    type: "mcp_registered",
                    server: result.server,
                    toolCount: result.toolCount
                  }),
                  "client-MCP"
                );
              } else if (result.kind === "unregistered") {
                safeWsSend(
                  ws,
                  JSON.stringify({
                    type: "mcp_unregistered",
                    server: result.server
                  }),
                  "client-MCP"
                );
              } else if (result.kind === "error") {
                safeWsSend(
                  ws,
                  JSON.stringify({
                    type: "mcp_error",
                    code: result.code,
                    message: result.message
                  }),
                  "client-MCP"
                );
              }
            }, "sendClientMcpAck");
            const dispatchOffQueue = frameType2 !== "mcp_message";
            if (dispatchOffQueue) {
              if (clientMcpInflightDispatch >= MAX_INFLIGHT_MCP_DISPATCH) {
                writeStderrLine(
                  `qwen serve: ${activeMount.routeLabel} client-MCP inflight cap hit (${MAX_INFLIGHT_MCP_DISPATCH}); rejecting ${String(frameType2)} frame`
                );
                safeWsSend(
                  ws,
                  JSON.stringify({
                    type: "mcp_error",
                    code: "too_many_inflight",
                    message: `too many concurrent client-MCP registrations (max ${MAX_INFLIGHT_MCP_DISPATCH})`
                  }),
                  "client-MCP"
                );
                return;
              }
              clientMcpInflightDispatch++;
            }
            const handleP = clientMcp.handleFrame(parsed).then(sendClientMcpAck, (err) => {
              const message2 = err instanceof Error ? err.message : String(err);
              writeStderrLine(
                `qwen serve: ${activeMount.routeLabel} client-mcp frame error: ${message2}`
              );
              if (dispatchOffQueue) {
                safeWsSend(
                  ws,
                  JSON.stringify({
                    type: "mcp_error",
                    code: "internal_error",
                    message: message2
                  }),
                  "client-MCP"
                );
              }
            }).finally(() => {
              if (dispatchOffQueue) clientMcpInflightDispatch--;
            });
            if (frameType2 === "mcp_message") {
              await handleP;
            }
            return;
          }
          if (opts.cdpTunnelOverWs === true && cdpEndpoint !== void 0 && parsed !== null && typeof parsed === "object" && isCdpInboundFrameType(parsed.type)) {
            cdpEndpoint.routeInbound(parsed);
            return;
          }
          const inbound = parseInbound(parsed);
          if (!inbound.ok) {
            ws.send(JSON.stringify(inbound.error));
            return;
          }
          const message = inbound.message;
          if (!initialized) {
            if (!isRequest(message) || message.method !== "initialize") {
              ws.send(
                JSON.stringify(
                  error(
                    isRequest(message) ? message.id : null,
                    RPC.INVALID_REQUEST,
                    "First message must be initialize"
                  )
                )
              );
              ws.close(1002, "Protocol error");
              return;
            }
            const conn2 = activeMount.registry.create(fromLoopback);
            if (!conn2) {
              ws.send(
                JSON.stringify(
                  error(
                    message.id,
                    RPC.INTERNAL_ERROR,
                    "Too many connections"
                  )
                )
              );
              ws.close(1013, "Connection cap");
              return;
            }
            const requestedVersion = message.params && typeof message.params === "object" && !Array.isArray(message.params) ? message.params["protocolVersion"] : void 0;
            const stream = new WsStream(
              ws,
              () => {
                writeStderrLine(
                  `qwen serve: ${activeMount.routeLabel} WS closed (${conn2.connectionId.slice(0, 8)})`
                );
                activeMount.registry.delete(conn2.connectionId);
              },
              () => conn2.touch()
            );
            conn2.attachConnStream(stream);
            ws.send(
              JSON.stringify({
                jsonrpc: "2.0",
                id: message.id,
                result: activeMount.dispatcher.buildInitializeResult(
                  conn2.connectionId,
                  requestedVersion
                )
              })
            );
            initialized = true;
            activeMount.pendingWebSockets.delete(ws);
            clearTimeout(initTimer);
            connRef = conn2;
            writeStderrLine(
              `qwen serve: ${activeMount.routeLabel} WS established ${conn2.connectionId.slice(0, 8)} (loopback=${fromLoopback}, active=${activeMount.registry.size})`
            );
            const clientName = message.params && typeof message.params === "object" && !Array.isArray(message.params) ? message.params["clientInfo"]?.name : void 0;
            if (activeMount.primary && opts.cdpTunnelOverWs === true && opts.cdpTunnelRegistry !== void 0 && clientName === CDP_BRIDGE_CLIENT_NAME) {
              cdpEndpoint = {
                connectionId: conn2.connectionId,
                send: /* @__PURE__ */ __name((frame) => safeWsSend(ws, JSON.stringify(frame), "CDP"), "send"),
                routeInbound: /* @__PURE__ */ __name(() => false, "routeInbound")
              };
              cdpBridgeUnregister = opts.cdpTunnelRegistry.register(cdpEndpoint);
              activeMount.ensureChromeDevToolsMcpRegistered(
                localPort,
                conn2.connectionId
              );
              writeStderrLine(
                `qwen serve: ${activeMount.routeLabel} connection ${conn2.connectionId.slice(0, 8)} registered as CDP bridge`
              );
            }
            return;
          }
          const conn = connRef;
          if (!conn || conn.destroyed) {
            ws.send(
              JSON.stringify(
                error(null, RPC.INTERNAL_ERROR, "Connection lost")
              )
            );
            ws.close(1011, "Connection lost");
            return;
          }
          if (isRequest(message) && message.params && typeof message.params === "object") {
            const sid = message.params["sessionId"];
            if (typeof sid === "string" && conn.ownsSession(sid)) {
              const binding = conn.sessions.get(sid);
              if (binding && !binding.stream && conn.connStream && !conn.connStream.isClosed) {
                const ac = new AbortController();
                conn.attachSessionStream(sid, conn.connStream, ac);
                const myAbort = ac;
                const cleanupSession = /* @__PURE__ */ __name(() => {
                  const b = conn.sessions.get(sid);
                  if (b?.stream === conn.connStream && b?.abort === myAbort) {
                    conn.closeSessionStream(sid);
                  }
                }, "cleanupSession");
                void activeMount.dispatcher.pumpSessionEvents(conn, sid, ac.signal).then(cleanupSession, (err) => {
                  writeStderrLine(
                    `qwen serve: ${activeMount.routeLabel} WS pump error (${sid}): ${err instanceof Error ? err.message : String(err)}`
                  );
                  cleanupSession();
                });
              }
            }
          }
          if (opts.checkRate && isRequest(message)) {
            const m = message.method;
            if (WS_EXEMPT_METHODS.has(m)) {
            } else {
              const tier = m === "session/prompt" || m === "_qwen/session/prompt" ? "prompt" : WS_READ_METHODS.has(m) ? "read" : "mutation";
              if (!opts.checkRate(workspaceRateLimitKey(activeMount, wsKey), tier)) {
                ws.send(
                  JSON.stringify(
                    error(
                      message.id,
                      RPC.INTERNAL_ERROR,
                      "Rate limit exceeded"
                    )
                  )
                );
                return;
              }
            }
          }
          const isPrompt = isRequest(message) && (message.method === "session/prompt" || message.method === "_qwen/session/prompt");
          const dispatchP = activeMount.dispatcher.handle(conn, message, void 0, fromLoopback).catch((err) => {
            writeStderrLine(
              `qwen serve: ${activeMount.routeLabel} WS handle error: ${err instanceof Error ? err.message : String(err)}`
            );
          });
          if (!isPrompt) await dispatchP;
        }
        __name(handleWsMessage, "handleWsMessage");
      });
    }, "upgradeListener");
    httpServer.on("upgrade", upgradeListener);
    writeStderrLine(`qwen serve: /acp WebSocket transport enabled on ${path15}`);
  }
  __name(setupWebSocket, "setupWebSocket");
  return {
    dispose: /* @__PURE__ */ __name(() => {
      if (disposed) return;
      disposed = true;
      if (upgradeServer && upgradeListener) {
        upgradeServer.removeListener("upgrade", upgradeListener);
        upgradeListener = void 0;
        upgradeServer = void 0;
      }
      registry.dispose();
      opts.workspaceRememberLane.dispose();
      for (const mount of secondaryMounts.values()) {
        mount.workspaceRememberLane.dispose();
        mount.registry.dispose();
      }
      drainingWorkspaceIds.clear();
      if (wss) {
        for (const client of wss.clients) {
          client.close(1012, "Server shutting down");
        }
        wss.close();
        wss = void 0;
      }
    }, "dispose"),
    registry,
    beginWorkspaceDrain: /* @__PURE__ */ __name((workspaceId) => {
      drainingWorkspaceIds.add(workspaceId);
      const mount = secondaryMounts.get(workspaceId);
      if (!mount) return;
      mount.draining = true;
      mount.workspaceRememberLane.beginDrain();
    }, "beginWorkspaceDrain"),
    cancelWorkspaceDrain: /* @__PURE__ */ __name((workspaceId) => {
      drainingWorkspaceIds.delete(workspaceId);
      const mount = secondaryMounts.get(workspaceId);
      if (!mount) return;
      mount.draining = false;
      mount.workspaceRememberLane.cancelDrain();
    }, "cancelWorkspaceDrain"),
    getWorkspaceActivity: /* @__PURE__ */ __name((workspaceId) => {
      const mount = secondaryMounts.get(workspaceId);
      return {
        acpConnections: (mount?.registry.size ?? 0) + (mount?.pendingWebSockets.size ?? 0),
        memoryTasks: mount?.workspaceRememberLane.pendingCount() ?? 0
      };
    }, "getWorkspaceActivity"),
    commitWorkspaceRemoval: /* @__PURE__ */ __name((workspaceId) => {
      secondaryMounts.get(workspaceId)?.workspaceRememberLane.dispose();
    }, "commitWorkspaceRemoval"),
    disposeWorkspace: /* @__PURE__ */ __name((workspaceId) => {
      drainingWorkspaceIds.delete(workspaceId);
      const mount = secondaryMounts.get(workspaceId);
      if (!mount) return;
      secondaryMounts.delete(workspaceId);
      try {
        mount.workspaceRememberLane.dispose();
      } finally {
        try {
          for (const ws of mount.webSockets) {
            ws.close(1012, "Workspace removed");
          }
        } finally {
          mount.registry.dispose();
        }
      }
    }, "disposeWorkspace"),
    getSnapshot: /* @__PURE__ */ __name(() => {
      const perMount = [
        {
          workspaceId: null,
          primary: true,
          workspaceCwd: primaryMount.workspaceCwd,
          snap: registry.getSnapshot()
        }
      ];
      for (const [workspaceId, mount] of secondaryMounts) {
        perMount.push({
          workspaceId,
          primary: false,
          workspaceCwd: mount.workspaceCwd,
          snap: mount.registry.getSnapshot()
        });
      }
      return {
        connectionCount: perMount.reduce(
          (n, m) => n + m.snap.connectionCount,
          0
        ),
        connectionStreams: perMount.reduce(
          (n, m) => n + m.snap.connectionStreams,
          0
        ),
        sessionStreams: perMount.reduce((n, m) => n + m.snap.sessionStreams, 0),
        sseStreams: perMount.reduce((n, m) => n + m.snap.sseStreams, 0),
        wsStreams: perMount.reduce((n, m) => n + m.snap.wsStreams, 0),
        pendingClientRequests: perMount.reduce(
          (n, m) => n + m.snap.pendingClientRequests,
          0
        ),
        mounts: perMount.map((m) => ({
          workspaceId: m.workspaceId,
          primary: m.primary,
          connectionCount: m.snap.connectionCount,
          wsStreams: m.snap.wsStreams
        })),
        connections: perMount.flatMap(
          (mount) => mount.snap.connections.map((connection) => ({
            ...connection,
            workspaceId: mount.workspaceId,
            workspaceCwd: mount.workspaceCwd,
            primary: mount.primary
          }))
        )
      };
    }, "getSnapshot"),
    attachServer(server) {
      setupWebSocket(server);
    }
  };
}
__name(mountAcpHttp, "mountAcpHttp");
function headerOf(req, name) {
  const v = req.headers[name];
  return Array.isArray(v) ? v[0] : v;
}
__name(headerOf, "headerOf");
function isLoopbackSocket(socket) {
  const addr = socket.remoteAddress;
  if (typeof addr !== "string") return false;
  return addr === "::1" || addr.startsWith("127.") || addr.startsWith("::ffff:127.");
}
__name(isLoopbackSocket, "isLoopbackSocket");
function isLoopbackReq(req) {
  const addr = req.socket?.remoteAddress;
  if (typeof addr !== "string") return false;
  return addr === "::1" || addr.startsWith("127.") || addr.startsWith("::ffff:127.");
}
__name(isLoopbackReq, "isLoopbackReq");

// packages/cli/src/serve/voice/voice-ws.ts
init_esbuild_shims();

// packages/cli/src/serve/voice/resolve-voice-config.ts
init_esbuild_shims();
function readVoiceModel2(settings) {
  const raw = settings.merged.voiceModel;
  if (typeof raw !== "string") return void 0;
  const trimmed = raw.trim();
  return trimmed.length > 0 ? trimmed : void 0;
}
__name(readVoiceModel2, "readVoiceModel");
function buildModelsConfig(settings, env) {
  const merged = settings.merged;
  const selectedAuthType = merged.security?.auth?.selectedType ?? getAuthTypeFromEnv(env);
  const resolvedCliConfig = resolveCliGenerationConfig({
    argv: {},
    settings: merged,
    selectedAuthType,
    env
  });
  return new ModelsConfig({
    initialAuthType: selectedAuthType,
    modelProvidersConfig: merged.modelProviders,
    generationConfig: resolvedCliConfig.generationConfig,
    generationConfigSources: resolvedCliConfig.sources
  });
}
__name(buildModelsConfig, "buildModelsConfig");
function loadDaemonVoiceContext(workspaceCwd, options = {}) {
  const settings = loadSettings(
    workspaceCwd,
    options.env ? { skipLoadEnvironment: true } : true
  );
  const voiceModel = readVoiceModel2(settings);
  if (!voiceModel) {
    throw new Error("No voice model is configured for this workspace.");
  }
  const models = buildModelsConfig(
    settings,
    options.env ?? snapshotProcessEnv()
  );
  resolveVoiceTranscriptionConfig({
    config: models,
    settings,
    voiceModel,
    env: options.env
  });
  return {
    settings,
    models,
    ...options.env ? { env: options.env } : {},
    voiceModel,
    streaming: isStreamingVoiceModel(voiceModel)
  };
}
__name(loadDaemonVoiceContext, "loadDaemonVoiceContext");

// packages/cli/src/serve/voice/voice-ws.ts
var debugLogger3 = createDebugLogger("VOICE_WS");
var MAX_BATCH_AUDIO_BYTES = 10 * 1024 * 1024;
var MAX_QUEUED_AUDIO_BYTES = MAX_BATCH_AUDIO_BYTES * 2;
var MAX_CONNECTION_MS = 6 * 6e4;
var GENERIC_TRANSCRIPTION_ERROR = "Voice transcription failed. Please try again.";
var NO_VOICE_MODEL_ERROR = "No voice model is configured for this workspace.";
var SAMPLE_RATE = 16e3;
function encodeWav(pcm) {
  const header = Buffer.alloc(44);
  const dataLen = pcm.byteLength;
  header.write("RIFF", 0);
  header.writeUInt32LE(36 + dataLen, 4);
  header.write("WAVE", 8);
  header.write("fmt ", 12);
  header.writeUInt32LE(16, 16);
  header.writeUInt16LE(1, 20);
  header.writeUInt16LE(1, 22);
  header.writeUInt32LE(SAMPLE_RATE, 24);
  header.writeUInt32LE(SAMPLE_RATE * 2, 28);
  header.writeUInt16LE(2, 32);
  header.writeUInt16LE(16, 34);
  header.write("data", 36);
  header.writeUInt32LE(dataLen, 40);
  return Buffer.concat([header, Buffer.from(pcm)]);
}
__name(encodeWav, "encodeWav");
async function defaultOpenStream(ctx, callbacks, abortSignal) {
  try {
    const cfg = resolveVoiceStreamConfig({
      config: ctx.models,
      settings: ctx.settings,
      voiceModel: ctx.voiceModel,
      env: ctx.env
    });
    await assertVoiceBaseUrlNetworkAllowed(cfg, void 0, abortSignal);
    return await openVoiceStreamWithRetry(
      () => cfg.transport === "qwen-asr-realtime" ? openQwenAsrRealtimeStream(cfg, callbacks, { abortSignal }) : openVoiceStream(cfg, callbacks, { abortSignal }),
      { abortSignal }
    );
  } catch (error2) {
    debugLogger3.debug(`[voice-ws] stream open error: ${errMessage(error2)}`);
    throw new Error(GENERIC_TRANSCRIPTION_ERROR);
  }
}
__name(defaultOpenStream, "defaultOpenStream");
function defaultTranscribe(ctx, pcm, abortSignal) {
  return transcribeVoiceAudio(
    { data: encodeWav(pcm), mimeType: "audio/wav" },
    {
      config: ctx.models,
      settings: ctx.settings,
      voiceModel: ctx.voiceModel,
      env: ctx.env,
      abortSignal
    }
  ).catch((error2) => {
    debugLogger3.debug(
      `[voice-ws] batch transcription error: ${errMessage(error2)}`
    );
    throw new Error(GENERIC_TRANSCRIPTION_ERROR);
  });
}
__name(defaultTranscribe, "defaultTranscribe");
function errMessage(error2) {
  return error2 instanceof Error ? error2.message : String(error2);
}
__name(errMessage, "errMessage");
function voiceLeaseCloseReason(signal) {
  return signal.reason instanceof VoiceLeaseAbortError && signal.reason.kind === "daemon_shutdown" ? "Server shutting down" : "Workspace removed";
}
__name(voiceLeaseCloseReason, "voiceLeaseCloseReason");
function voiceConfigErrorMessage(error2) {
  const message = errMessage(error2);
  return message === NO_VOICE_MODEL_ERROR ? message : GENERIC_TRANSCRIPTION_ERROR;
}
__name(voiceConfigErrorMessage, "voiceConfigErrorMessage");
function toBuffer(data) {
  if (Buffer.isBuffer(data)) return data;
  if (Array.isArray(data)) return Buffer.concat(data);
  return Buffer.from(data);
}
__name(toBuffer, "toBuffer");
function parseControl(text) {
  let parsed;
  try {
    parsed = JSON.parse(text);
  } catch {
    return void 0;
  }
  const type = parsed?.type;
  if (type === "start" || type === "stop" || type === "abort") {
    return { type };
  }
  return void 0;
}
__name(parseControl, "parseControl");
function createVoiceWsConnectionHandler(boundWorkspace, deps = {}) {
  const loadContext = deps.loadContext ?? ((workspaceCwd) => loadDaemonVoiceContext(workspaceCwd, { env: deps.env }));
  const openStream = deps.openStream ?? defaultOpenStream;
  const transcribe = deps.transcribe ?? defaultTranscribe;
  let activeSessions = 0;
  const acquireLocalLease = /* @__PURE__ */ __name(() => {
    if (activeSessions >= MAX_CONCURRENT_VOICE_SESSIONS) {
      return { kind: "rejected", reason: "capacity" };
    }
    activeSessions++;
    const controller = new AbortController();
    let released = false;
    const lease = {
      signal: controller.signal,
      release: /* @__PURE__ */ __name(() => {
        if (released) return;
        released = true;
        activeSessions--;
      }, "release")
    };
    return { kind: "admitted", lease };
  }, "acquireLocalLease");
  return (ws) => {
    const admission = (deps.acquireVoiceLease ?? acquireLocalLease)();
    if (admission.kind === "rejected") {
      writeStderrLine("qwen serve: voice websocket rejected");
      try {
        if (admission.reason === "draining") {
          ws.close(1012, "Workspace removed");
          return;
        }
        ws.send(
          JSON.stringify({
            type: "error",
            message: "Too many voice sessions in progress; try again shortly."
          })
        );
        ws.close(1013, "busy");
      } catch {
      }
      return;
    }
    const lease = admission.lease;
    writeStderrLine("qwen serve: voice websocket accepted");
    let released = false;
    const releaseSlot = /* @__PURE__ */ __name(() => {
      if (!released) {
        released = true;
        lease.release();
        writeStderrLine("qwen serve: voice websocket slot released");
      }
    }, "releaseSlot");
    let state = "idle";
    let ctx;
    let session;
    let sessionPromise;
    const pcmChunks = [];
    let bufferedBytes = 0;
    let queuedBytes = 0;
    let pendingOperations = 0;
    const operationController = new AbortController();
    let chain = Promise.resolve();
    const hardTimer = setTimeout(() => {
      if (state !== "closed") fail("Voice session exceeded the time limit.");
    }, MAX_CONNECTION_MS);
    hardTimer.unref?.();
    const isClosed = /* @__PURE__ */ __name(() => state === "closed", "isClosed");
    const releaseSlotWhenIdle = /* @__PURE__ */ __name(() => {
      if (state === "closed" && pendingOperations === 0) releaseSlot();
    }, "releaseSlotWhenIdle");
    const sendJson = /* @__PURE__ */ __name((obj) => {
      if (ws.readyState === ws.OPEN) {
        try {
          ws.send(JSON.stringify(obj));
        } catch {
        }
      }
    }, "sendJson");
    function cleanup() {
      state = "closed";
      clearTimeout(hardTimer);
      if (!operationController.signal.aborted) {
        operationController.abort(new Error("Voice connection closed."));
      }
      if (session) {
        try {
          session.abort();
        } catch {
        }
        session = void 0;
      }
      sessionPromise = void 0;
      pcmChunks.length = 0;
      bufferedBytes = 0;
      queuedBytes = 0;
    }
    __name(cleanup, "cleanup");
    lease.signal.addEventListener(
      "abort",
      () => {
        if (state === "closed") return;
        cleanup();
        try {
          ws.close(1012, voiceLeaseCloseReason(lease.signal));
        } catch {
        }
        releaseSlotWhenIdle();
      },
      { once: true }
    );
    function fail(message) {
      if (state === "closed") return;
      writeStderrLine(`qwen serve: voice websocket failed: ${message}`);
      sendJson({ type: "error", message });
      cleanup();
      releaseSlotWhenIdle();
      try {
        ws.close(1011, "voice error");
      } catch {
      }
    }
    __name(fail, "fail");
    async function ensureStarted() {
      if (ctx) return;
      try {
        ctx = loadContext(boundWorkspace);
      } catch (error2) {
        debugLogger3.debug(
          `[voice-ws] load context error: ${errMessage(error2)}`
        );
        fail(voiceConfigErrorMessage(error2));
        return;
      }
      sendJson({
        type: "ready",
        streaming: ctx.streaming,
        model: ctx.voiceModel
      });
      if (ctx.streaming) {
        const callbacks = {
          onInterim: /* @__PURE__ */ __name((text) => sendJson({ type: "interim", text }), "onInterim"),
          onError: /* @__PURE__ */ __name((error2) => {
            debugLogger3.debug(
              `[voice-ws] upstream error: ${errMessage(error2)}`
            );
            fail(GENERIC_TRANSCRIPTION_ERROR);
          }, "onError")
        };
        const opening = openStream(ctx, callbacks, operationController.signal);
        sessionPromise = opening;
        const opened = await opening;
        if (state === "closed") {
          try {
            opened.abort();
          } catch {
          }
          return;
        }
        session = opened;
      }
      if (state === "idle") state = "active";
    }
    __name(ensureStarted, "ensureStarted");
    async function finalize() {
      if (state === "closed" || state === "finalizing") return;
      state = "finalizing";
      await ensureStarted();
      if (isClosed()) return;
      let transcript = "";
      if (ctx.streaming) {
        const active = session ?? (sessionPromise ? await sessionPromise : void 0);
        if (isClosed()) return;
        if (active) {
          try {
            transcript = await active.finish();
          } finally {
            session = void 0;
          }
        }
      } else if (pcmChunks.length > 0) {
        transcript = await transcribe(
          ctx,
          Buffer.concat(pcmChunks),
          operationController.signal
        );
      }
      sendJson({ type: "final", text: transcript });
      writeStderrLine("qwen serve: voice websocket finalized successfully");
      cleanup();
      releaseSlotWhenIdle();
      try {
        ws.close(1e3, "done");
      } catch {
      }
    }
    __name(finalize, "finalize");
    async function handleMessage(data, isBinary) {
      if (state === "closed" || state === "finalizing") return;
      if (isBinary) {
        await ensureStarted();
        if (isClosed()) return;
        if (ctx.streaming) {
          const active = session ?? (sessionPromise ? await sessionPromise : void 0);
          active?.pushAudio(data);
        } else {
          bufferedBytes += data.byteLength;
          if (bufferedBytes > MAX_BATCH_AUDIO_BYTES) {
            fail("Recording is too long for transcription (max ~5 minutes).");
            return;
          }
          pcmChunks.push(data);
        }
        return;
      }
      const control = parseControl(data.toString("utf8"));
      if (!control) return;
      switch (control.type) {
        case "start":
          writeStderrLine("qwen serve: voice websocket start received");
          await ensureStarted();
          return;
        case "stop":
          writeStderrLine("qwen serve: voice websocket stop received");
          await finalize();
          return;
        default:
          return;
      }
    }
    __name(handleMessage, "handleMessage");
    ws.on("message", (data, isBinary) => {
      const buf = toBuffer(data);
      if (!isBinary) {
        const control = parseControl(buf.toString("utf8"));
        if (control?.type === "abort") {
          writeStderrLine("qwen serve: voice websocket abort received");
          cleanup();
          try {
            ws.close(1e3, "aborted");
          } catch {
          }
          releaseSlotWhenIdle();
          return;
        }
      }
      const queuedSize = isBinary ? buf.byteLength : 0;
      if (queuedSize > 0) {
        queuedBytes += queuedSize;
        if (queuedBytes > MAX_QUEUED_AUDIO_BYTES) {
          fail("Queued voice audio exceeded the memory limit.");
          releaseSlotWhenIdle();
          return;
        }
      }
      chain = chain.then(async () => {
        pendingOperations++;
        try {
          await handleMessage(buf, isBinary);
        } finally {
          if (queuedSize > 0) {
            queuedBytes = Math.max(0, queuedBytes - queuedSize);
          }
          pendingOperations--;
          releaseSlotWhenIdle();
        }
      }).catch((error2) => {
        debugLogger3.debug(`[voice-ws] ${errMessage(error2)}`);
        fail(GENERIC_TRANSCRIPTION_ERROR);
        releaseSlotWhenIdle();
      });
    });
    ws.on("close", () => {
      if (state !== "closed") cleanup();
      releaseSlotWhenIdle();
    });
    ws.on("error", (error2) => {
      debugLogger3.debug(`[voice-ws] socket error: ${error2.message}`);
      if (state !== "closed") cleanup();
      releaseSlotWhenIdle();
    });
  };
}
__name(createVoiceWsConnectionHandler, "createVoiceWsConnectionHandler");

// packages/cli/src/serve/cdp-tunnel/cdp-tunnel-registry.ts
init_esbuild_shims();
var CdpTunnelRegistry = class {
  static {
    __name(this, "CdpTunnelRegistry");
  }
  active;
  /**
   * Register (or replace) the active extension bridge. Returns an unregister
   * callback the `/acp` WS layer calls on socket close. Last-writer-wins: a new
   * extension connection supersedes the previous bridge.
   */
  register(endpoint) {
    const previous = this.active;
    if (previous && previous !== endpoint) {
      writeStderrLine(
        `qwen serve: /cdp tunnel \u2014 extension bridge '${endpoint.connectionId}' superseded the stale '${previous.connectionId}'`
      );
      previous.onExtensionGone?.();
    }
    this.active = endpoint;
    let unregistered = false;
    return () => {
      if (unregistered) return;
      unregistered = true;
      if (this.active === endpoint) this.active = void 0;
      endpoint.onExtensionGone?.();
    };
  }
  /** The active extension bridge, if any. */
  getActive() {
    return this.active;
  }
  /** Whether an extension bridge is currently registered. */
  hasActive() {
    return this.active !== void 0;
  }
  /**
   * Route an inbound `cdp_*` frame (from the extension `/acp` socket) to the
   * active bridge's bound reverse link. Returns true if consumed.
   */
  routeInbound(frame) {
    return this.active ? this.active.routeInbound(frame) : false;
  }
};

// packages/cli/src/serve/web-shell-static.ts
init_esbuild_shims();
var import_express2 = __toESM(require_express(), 1);
import * as path10 from "node:path";
var WEB_SHELL_CSP_DIRECTIVES = [
  "default-src 'self'",
  "script-src 'self' 'unsafe-inline' 'unsafe-eval' 'wasm-unsafe-eval'",
  "style-src 'self' 'unsafe-inline'",
  "font-src 'self' data:",
  "img-src 'self' data: blob:",
  "connect-src 'self'",
  "worker-src 'self' blob:",
  // base-uri does NOT fall back to default-src; lock it so an injected <base>
  // (the SPA renders AI-generated markdown) cannot repoint relative URLs to an
  // attacker origin.
  "base-uri 'none'"
];
function buildWebShellCsp(frameAncestors = []) {
  const fa = frameAncestors.length ? `frame-ancestors ${frameAncestors.join(" ")}` : "frame-ancestors 'none'";
  return [...WEB_SHELL_CSP_DIRECTIVES, fa].join("; ");
}
__name(buildWebShellCsp, "buildWebShellCsp");
var WEB_SHELL_CSP = buildWebShellCsp();
function isDocumentNavigation(req) {
  const fetchMode = req.headers["sec-fetch-mode"];
  const fetchDest = req.headers["sec-fetch-dest"];
  const accept = req.headers.accept ?? "";
  return fetchMode === "navigate" || fetchDest === "document" || accept.trim().toLowerCase().startsWith("text/html");
}
__name(isDocumentNavigation, "isDocumentNavigation");
function createSendIndex(webShellDir, frameAncestors = []) {
  const indexPath = path10.join(webShellDir, "index.html");
  const csp = buildWebShellCsp(frameAncestors);
  return (res) => {
    res.status(200).set("Content-Security-Policy", csp).set("X-Content-Type-Options", "nosniff").set("Referrer-Policy", "no-referrer").set(
      // `microphone=(self)` lets the same-origin Web Shell document request
      // the mic for voice dictation (the prompt won't even appear under an
      // empty `microphone=()` allowlist). Still blocks cross-origin iframes;
      // camera/geolocation/payment stay disabled (unused).
      "Permissions-Policy",
      "camera=(), microphone=(self), geolocation=(), payment=()"
    ).set("Cache-Control", "no-cache");
    if (frameAncestors.length === 0) {
      res.set("X-Frame-Options", "DENY");
    }
    res.sendFile(
      indexPath,
      { cacheControl: false, dotfiles: "allow" },
      (err) => {
        if (!err) return;
        writeStderrLine(
          `qwen serve: Web Shell index send failed: ${err instanceof Error ? err.message : String(err)}`
        );
        if (!res.headersSent) {
          res.status(500).type("text/plain").send("Failed to load Web Shell");
        } else {
          res.end();
        }
      }
    );
  };
}
__name(createSendIndex, "createSendIndex");
function mountWebShellAssets(app, webShellDir, frameAncestors = []) {
  const sendIndex = createSendIndex(webShellDir, frameAncestors);
  app.use(
    "/assets",
    import_express2.default.static(path10.join(webShellDir, "assets"), {
      index: false,
      immutable: true,
      maxAge: "1y"
    })
  );
  app.use("/assets", (req, res) => {
    if (isServeDebugMode()) {
      writeStderrLine(
        `qwen serve: Web Shell asset not found: ${req.originalUrl}`
      );
    }
    res.status(404).type("text/plain").send("Not found");
  });
  app.get("/", (_req, res) => sendIndex(res));
}
__name(mountWebShellAssets, "mountWebShellAssets");
function mountWebShellSpaFallback(app, webShellDir, frameAncestors = []) {
  const sendIndex = createSendIndex(webShellDir, frameAncestors);
  app.use((req, res, next) => {
    if (req.method !== "GET" && req.method !== "HEAD") return next();
    if (!isDocumentNavigation(req)) return next();
    if (isServeDebugMode()) {
      writeStderrLine(
        `qwen serve: Web Shell SPA fallback served for ${req.method} ${req.originalUrl}`
      );
    }
    sendIndex(res);
  });
}
__name(mountWebShellSpaFallback, "mountWebShellSpaFallback");

// packages/cli/src/serve/routes/daemon-status.ts
init_esbuild_shims();
function registerDaemonStatusRoutes(app, deps) {
  app.get("/daemon/status", async (req, res) => {
    const detail = parseDaemonStatusDetail(req.query["detail"]);
    if (!detail.ok || !detail.detail) {
      res.status(400).json({
        error: "detail must be one of: summary, full",
        code: "invalid_detail"
      });
      return;
    }
    try {
      res.status(200).json(
        await buildDaemonStatusResponse(detail.detail, {
          opts: deps.opts,
          boundWorkspace: deps.boundWorkspace,
          bridge: deps.bridge,
          workspaceRegistry: deps.workspaceRegistry,
          workspace: deps.workspace,
          daemonLog: deps.daemonLog,
          startup: deps.startup,
          qwenCodeVersion: deps.qwenCodeVersion,
          acpHandle: deps.getAcpHandle(),
          rateLimiter: deps.getRateLimiter(),
          getRestSseActive: deps.getRestSseActive,
          features: deps.currentServeFeatures(),
          protocolVersions: getServeProtocolVersions(),
          supportedDeviceFlowProviders: deps.getSupportedDeviceFlowProviders(),
          deviceFlowRegistry: deps.deviceFlowRegistry,
          sessionShellCommandEnabled: deps.sessionShellCommandEnabled,
          getChannelWorkerSnapshot: deps.getChannelWorkerSnapshot,
          getChannelWorkerSnapshots: deps.getChannelWorkerSnapshots,
          getPerfSnapshot: deps.getPerfSnapshot,
          getMetricsSeries: deps.getMetricsSeries,
          getTotalSessionAdmissionSnapshot: deps.getTotalSessionAdmissionSnapshot
        })
      );
    } catch (err) {
      writeStderrLine(
        `qwen serve: /daemon/status failed: ${err instanceof Error ? err.message : String(err)}`
      );
      res.status(500).json({
        error: "Failed to build daemon status",
        code: "daemon_status_failed"
      });
    }
  });
}
__name(registerDaemonStatusRoutes, "registerDaemonStatusRoutes");

// packages/cli/src/serve/routes/health-demo.ts
init_esbuild_shims();

// packages/cli/src/serve/demo.ts
init_esbuild_shims();
function getDemoHtml(_port) {
  return (
    /* html */
    `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Qwen Serve Demo</title>
<style>
  :root { --bg: #1a1a2e; --surface: #16213e; --border: #0f3460; --accent: #e94560; --text: #eee; --text2: #aab; --ok: #4ade80; --warn: #fbbf24; --err: #f87171; }
  * { box-sizing: border-box; margin: 0; padding: 0; }
  body { font-family: 'SF Mono', 'Menlo', 'Consolas', monospace; font-size: 13px; background: var(--bg); color: var(--text); min-height: 100vh; }
  .header { background: var(--surface); border-bottom: 1px solid var(--border); padding: 12px 20px; display: flex; align-items: center; gap: 12px; }
  .header h1 { font-size: 16px; font-weight: 600; }
  .header .badge { font-size: 11px; background: var(--accent); color: #fff; padding: 2px 8px; border-radius: 10px; }
  .header .status { margin-left: auto; display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text2); }
  .header .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--err); }
  .header .dot.ok { background: var(--ok); }
  .container { display: grid; grid-template-columns: 340px 1fr; height: calc(100vh - 49px); }
  .sidebar { background: var(--surface); border-right: 1px solid var(--border); overflow-y: auto; padding: 12px; display: flex; flex-direction: column; gap: 12px; }
  .panel { background: var(--bg); border: 1px solid var(--border); border-radius: 6px; padding: 12px; }
  .panel h3 { font-size: 12px; color: var(--accent); margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.5px; }
  .panel label { display: block; font-size: 11px; color: var(--text2); margin-bottom: 3px; }
  .panel input, .panel textarea { width: 100%; background: var(--surface); border: 1px solid var(--border); color: var(--text); padding: 6px 8px; border-radius: 4px; font-family: inherit; font-size: 12px; margin-bottom: 8px; }
  .panel input:focus, .panel textarea:focus { outline: none; border-color: var(--accent); }
  .panel textarea { resize: vertical; min-height: 60px; }
  .btn { display: inline-flex; align-items: center; gap: 4px; padding: 6px 14px; border: 1px solid var(--border); border-radius: 4px; background: var(--surface); color: var(--text); font-family: inherit; font-size: 12px; cursor: pointer; transition: all 0.15s; }
  .btn:hover { border-color: var(--accent); color: var(--accent); }
  .btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
  .btn.primary:hover { opacity: 0.85; }
  .btn:disabled { opacity: 0.4; cursor: not-allowed; }
  .btn-row { display: flex; gap: 6px; flex-wrap: wrap; }
  .main { display: flex; flex-direction: column; overflow: hidden; }
  .tabs { display: flex; background: var(--surface); border-bottom: 1px solid var(--border); }
  .tab { padding: 8px 16px; font-size: 12px; color: var(--text2); cursor: pointer; border-bottom: 2px solid transparent; }
  .tab.active { color: var(--accent); border-bottom-color: var(--accent); }
  .tab-content { flex: 1; overflow: hidden; display: none; flex-direction: column; }
  .tab-content.active { display: flex; }
  .log { flex: 1; overflow-y: auto; padding: 12px; font-size: 12px; line-height: 1.6; }
  .log-entry { padding: 3px 0; border-bottom: 1px solid rgba(255,255,255,0.03); word-break: break-all; }
  .log-entry .ts { color: var(--text2); margin-right: 8px; font-size: 11px; }
  .log-entry .tag { display: inline-block; padding: 0 5px; border-radius: 3px; font-size: 10px; margin-right: 6px; }
  .tag-info { background: #1e40af; color: #93c5fd; }
  .tag-event { background: #065f46; color: #6ee7b7; }
  .tag-error { background: #7f1d1d; color: #fca5a5; }
  .tag-response { background: #713f12; color: #fde68a; }
  .tag-thought { background: #4c1d95; color: #c4b5fd; }
  .tag-message { background: #164e63; color: #67e8f9; }
  .chat { flex: 1; overflow-y: auto; padding: 16px; }
  .chat-msg { margin-bottom: 12px; max-width: 85%; }
  .chat-msg.user { margin-left: auto; }
  .chat-msg .bubble { padding: 8px 12px; border-radius: 8px; line-height: 1.5; white-space: pre-wrap; }
  .chat-msg.user .bubble { background: var(--accent); color: #fff; border-bottom-right-radius: 2px; }
  .chat-msg.assistant .bubble { background: var(--surface); border: 1px solid var(--border); border-bottom-left-radius: 2px; }
  .chat-msg .meta { font-size: 10px; color: var(--text2); margin-top: 3px; }
  .chat-input { display: flex; gap: 8px; padding: 12px; border-top: 1px solid var(--border); background: var(--surface); }
  .chat-input input { flex: 1; }
  .session-info { font-size: 11px; color: var(--text2); padding: 4px 0; }
  .session-info span { color: var(--ok); }
  .empty-hint { color: var(--text2); text-align: center; padding: 40px 20px; font-size: 12px; }
  .permission-card { background: var(--surface); border: 1px solid var(--warn); border-radius: 6px; padding: 10px 12px; margin: 8px 0; }
  .permission-card h4 { color: var(--warn); font-size: 12px; margin-bottom: 6px; }
  .permission-card .opt-btn { margin-right: 4px; margin-top: 4px; }
</style>
</head>
<body>

<div class="header">
  <h1>Qwen Serve</h1>
  <span class="badge">Demo</span>
  <div class="status">
    <span class="dot" id="statusDot"></span>
    <span id="statusText">Connecting...</span>
  </div>
</div>

<div class="container">
  <div class="sidebar">
    <div class="panel">
      <h3>Session</h3>
      <label>Working Directory (cwd)</label>
      <input type="text" id="cwdInput" placeholder="/path/to/project" />
      <div class="btn-row">
        <button class="btn primary" id="btnCreateSession">Create / Attach</button>
        <button class="btn" id="btnListSessions">List</button>
      </div>
      <div class="session-info" id="sessionInfo" style="display:none">
        Session: <span id="sessionIdDisplay"></span>
      </div>
    </div>

    <div class="panel">
      <h3>Prompt</h3>
      <textarea id="promptInput" placeholder="Type your prompt here..."></textarea>
      <div class="btn-row">
        <button class="btn primary" id="btnSendPrompt" disabled>Send</button>
        <button class="btn" id="btnCancel" disabled>Cancel</button>
      </div>
    </div>

    <div class="panel">
      <h3>Model</h3>
      <input type="text" id="modelInput" placeholder="Model ID (e.g. qwen3-coder)" />
      <button class="btn" id="btnSetModel" disabled>Switch Model</button>
    </div>

    <div class="panel">
      <h3>Auth Token</h3>
      <label>Bearer Token (if --token is set)</label>
      <input type="password" id="tokenInput" placeholder="Optional bearer token" />
    </div>

    <div class="panel">
      <h3>Quick Actions</h3>
      <div class="btn-row">
        <button class="btn" id="btnHealth">Health</button>
        <button class="btn" id="btnHealthDeep">Health (deep)</button>
        <button class="btn" id="btnCaps">Capabilities</button>
      </div>
    </div>

    <div class="panel" id="permissionPanel" style="display:none">
      <h3>Pending Permissions</h3>
      <div id="permissionList"></div>
    </div>
  </div>

  <div class="main">
    <div class="tabs">
      <div class="tab active" data-tab="chat">Chat</div>
      <div class="tab" data-tab="events">Events</div>
      <div class="tab" data-tab="requests">API Log</div>
    </div>

    <div class="tab-content active" id="tab-chat">
      <div class="chat" id="chatArea">
        <div class="empty-hint">Create a session to start chatting</div>
      </div>
      <div class="chat-input">
        <input type="text" id="chatInput" placeholder="Send a message..." disabled />
        <button class="btn primary" id="btnChatSend" disabled>Send</button>
      </div>
    </div>

    <div class="tab-content" id="tab-events">
      <div class="log" id="eventLog"></div>
    </div>

    <div class="tab-content" id="tab-requests">
      <div class="log" id="requestLog"></div>
    </div>
  </div>
</div>

<script>
(function() {
  const BASE = '';
  let sessionId = null;
  let eventSource = null;
  let currentAssistantBubble = null;
  let currentThought = '';

  // --- DOM refs ---
  const $ = (s) => document.querySelector(s);
  const statusDot = $('#statusDot');
  const statusText = $('#statusText');
  const cwdInput = $('#cwdInput');
  const promptInput = $('#promptInput');
  const modelInput = $('#modelInput');
  const tokenInput = $('#tokenInput');
  const chatArea = $('#chatArea');
  const chatInput = $('#chatInput');
  const eventLog = $('#eventLog');
  const requestLog = $('#requestLog');
  const sessionInfo = $('#sessionInfo');
  const sessionIdDisplay = $('#sessionIdDisplay');
  const permissionPanel = $('#permissionPanel');
  const permissionList = $('#permissionList');

  // --- Tabs ---
  document.querySelectorAll('.tab').forEach(tab => {
    tab.addEventListener('click', () => {
      document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
      document.querySelectorAll('.tab-content').forEach(t => t.classList.remove('active'));
      tab.classList.add('active');
      $('#tab-' + tab.dataset.tab).classList.add('active');
    });
  });

  // --- Logging ---
  function ts() {
    return new Date().toLocaleTimeString('en-US', { hour12: false, hour: '2-digit', minute: '2-digit', second: '2-digit' });
  }
  const MAX_LOG_ENTRIES = 500;
  function addLog(container, tag, tagClass, msg) {
    const el = document.createElement('div');
    el.className = 'log-entry';
    const text = typeof msg === 'object' ? JSON.stringify(msg, null, 2) : msg;
    const tsSpan = document.createElement('span');
    tsSpan.className = 'ts';
    tsSpan.textContent = ts();
    const tagSpan = document.createElement('span');
    tagSpan.className = 'tag ' + tagClass;
    tagSpan.textContent = tag;
    el.appendChild(tsSpan);
    el.appendChild(tagSpan);
    el.appendChild(document.createTextNode(text));
    container.appendChild(el);
    while (container.children.length > MAX_LOG_ENTRIES) {
      container.removeChild(container.firstChild);
    }
    container.scrollTop = container.scrollHeight;
  }
  function logEvent(tag, msg) { addLog(eventLog, tag, 'tag-event', msg); }
  function logRequest(tag, msg) { addLog(requestLog, tag, 'tag-info', msg); }
  function logResponse(tag, msg) { addLog(requestLog, tag, 'tag-response', msg); }
  function logError(tag, msg) { addLog(requestLog, tag, 'tag-error', msg); }

  function escHtml(s) {
    const d = document.createElement('div');
    d.textContent = String(s);
    return d.innerHTML;
  }

  // --- 401 token hint ---
  let tokenHintTimer = null;
  function highlightTokenInput(msg) {
    tokenInput.style.borderColor = 'var(--warn)';
    tokenInput.focus();
    // Show hint text below the input
    let hint = document.getElementById('tokenHint');
    if (!hint) {
      hint = document.createElement('div');
      hint.id = 'tokenHint';
      hint.style.cssText = 'font-size:11px;color:var(--warn);margin-top:-4px;margin-bottom:4px;';
      tokenInput.parentNode.insertBefore(hint, tokenInput.nextSibling);
    }
    hint.textContent = msg;
    if (tokenHintTimer) clearTimeout(tokenHintTimer);
    tokenHintTimer = setTimeout(() => {
      tokenInput.style.borderColor = '';
      hint.textContent = '';
    }, 6000);
  }

  // --- API helpers ---
  function authHeaders() {
    const token = tokenInput.value.trim();
    return token ? { 'Authorization': 'Bearer ' + token } : {};
  }

  async function api(method, path, body) {
    const opts = { method, headers: { ...authHeaders() } };
    if (body !== undefined) {
      opts.headers['Content-Type'] = 'application/json';
      opts.body = JSON.stringify(body);
    }
    logRequest(method, path + (body ? ' ' + JSON.stringify(body) : ''));
    try {
      const res = await fetch(BASE + path, opts);
      const text = await res.text();
      let data;
      try { data = JSON.parse(text); } catch { data = text; }
      if (!res.ok) {
        logError(res.status, JSON.stringify(data));
        if (res.status === 401) {
          highlightTokenInput('API returned 401 \u2014 enter your bearer token below');
        }
        return { ok: false, status: res.status, data };
      }
      logResponse(res.status, JSON.stringify(data));
      return { ok: true, status: res.status, data };
    } catch (err) {
      logError('ERR', err.message);
      return { ok: false, status: 0, data: { error: err.message } };
    }
  }

  // --- Health check on load ---
  async function checkHealth() {
    const r = await api('GET', '/health');
    if (r.ok) {
      statusDot.classList.add('ok');
      statusText.textContent = 'Connected';
    } else {
      statusDot.classList.remove('ok');
      statusText.textContent = 'Disconnected';
    }
  }

  // --- Session ---
  async function createSession() {
    const cwd = cwdInput.value.trim();
    if (!cwd) { alert('Please enter a working directory'); return; }
    const r = await api('POST', '/session', { cwd });
    if (r.ok) {
      sessionId = r.data.sessionId;
      sessionInfo.style.display = 'block';
      sessionIdDisplay.textContent = sessionId;
      enablePrompt(true);
      chatArea.innerHTML = '';
      currentAssistantBubble = null;
      pendingPerms.clear();
      renderPermissions();
      if (r.data.attached) {
        addChatMeta('Attached to existing session');
      } else {
        addChatMeta('New session created');
      }
      connectSSE();
    } else {
      const msg = r.data.error || 'session creation failed (' + r.status + ')';
      addChatMeta('Error: ' + msg);
      if (r.status === 401) highlightTokenInput('Token required or invalid');
    }
  }

  function enablePrompt(on) {
    $('#btnSendPrompt').disabled = !on;
    $('#btnCancel').disabled = !on;
    $('#btnSetModel').disabled = !on;
    chatInput.disabled = !on;
    $('#btnChatSend').disabled = !on;
  }

  // --- SSE ---
  function connectSSE() {
    if (eventSource) { eventSource.close(); }
    const url = BASE + '/session/' + sessionId + '/events';
    logEvent('SSE', 'Connecting to ' + url);

    // Use fetch-based SSE to avoid Origin header issues with EventSource
    const abort = new AbortController();
    eventSource = { close: () => abort.abort() };

    (async function readSSE() {
      try {
        const hdrs = authHeaders();
        const res = await fetch(url, { signal: abort.signal, headers: hdrs });
        if (!res.ok) {
          logEvent('SSE-ERR', 'HTTP ' + res.status);
          statusDot.classList.remove('ok');
          statusText.textContent = 'SSE failed (' + res.status + ')';
          enablePrompt(false);
          if (res.status === 401) {
            highlightTokenInput('SSE returned 401 \u2014 enter your bearer token and recreate the session');
          }
          return;
        }
        const reader = res.body.getReader();
        const decoder = new TextDecoder();
        let buffer = '';
        let currentEvent = {};

        while (true) {
          const { done, value } = await reader.read();
          if (done) break;
          buffer += decoder.decode(value, { stream: true });

          const lines = buffer.split('\\n');
          buffer = lines.pop();

          for (const line of lines) {
            if (line.startsWith('data: ')) {
              currentEvent.data = line.slice(6);
            } else if (line.startsWith('event: ')) {
              currentEvent.event = line.slice(7);
            } else if (line.startsWith('id: ')) {
              currentEvent.id = line.slice(4);
            } else if (line === '') {
              if (currentEvent.data) {
                handleSSEMessage(currentEvent);
              }
              currentEvent = {};
            }
          }
        }
        // Process any remaining buffered data
        if (currentEvent.data) handleSSEMessage(currentEvent);
        statusDot.classList.remove('ok');
        statusText.textContent = 'SSE stream ended';
        enablePrompt(false);
        logEvent('SSE', 'Stream ended by server');
      } catch (err) {
        if (err.name !== 'AbortError') {
          logEvent('SSE-ERR', err.message);
          statusDot.classList.remove('ok');
          statusText.textContent = 'SSE error';
          enablePrompt(false);
        }
      }
    })();
  }

  function handleSSEMessage(msg) {
    let data;
    try { data = JSON.parse(msg.data); } catch { data = msg.data; }
    const type = data.type || msg.event || 'unknown';

    if (type === 'session_update' && data.data) {
      const update = data.data.update || data.data;
      const kind = update.sessionUpdate;

      if (kind === 'agent_message_chunk') {
        const text = update.content?.text || '';
        if (text) appendAssistantChunk(text);
        if (update._meta?.usage) {
          const u = update._meta.usage;
          addChatMeta('tokens: in=' + u.inputTokens + ' out=' + u.outputTokens + ' | ' + (update._meta.durationMs || 0) + 'ms');
          currentAssistantBubble = null;
        }
        logEvent('MSG', text || '(usage meta)');
      } else if (kind === 'agent_thought_chunk') {
        const text = update.content?.text || '';
        currentThought += text;
        logEvent('THINK', text);
      } else {
        logEvent(kind || type, JSON.stringify(update));
      }
    } else if (type === 'permission_request') {
      handlePermissionRequest(data);
      logEvent('PERM', JSON.stringify(data.data));
    } else if (type === 'permission_resolved') {
      logEvent('PERM-OK', JSON.stringify(data.data));
      removePermission(data.data?.requestId);
    } else if (type === 'session_died') {
      addChatMeta('Session died: ' + JSON.stringify(data.data));
      logEvent('DIED', JSON.stringify(data.data));
      enablePrompt(false);
    } else if (type === 'model_switched') {
      addChatMeta('Model switched: ' + JSON.stringify(data.data));
      logEvent('MODEL', JSON.stringify(data.data));
    } else {
      logEvent(type, JSON.stringify(data));
    }
  }

  // --- Chat UI ---
  function addUserMessage(text) {
    currentAssistantBubble = null;
    currentThought = '';
    const el = document.createElement('div');
    el.className = 'chat-msg user';
    el.innerHTML = '<div class="bubble">' + escHtml(text) + '</div>';
    chatArea.appendChild(el);
    chatArea.scrollTop = chatArea.scrollHeight;
  }

  function appendAssistantChunk(text) {
    if (!currentAssistantBubble) {
      if (currentThought) {
        const te = document.createElement('div');
        te.className = 'chat-msg assistant';
        te.innerHTML = '<div class="bubble" style="color:var(--text2);font-style:italic;border-color:var(--border)">Thinking: ' + escHtml(currentThought) + '</div>';
        chatArea.appendChild(te);
        currentThought = '';
      }
      const el = document.createElement('div');
      el.className = 'chat-msg assistant';
      el.innerHTML = '<div class="bubble"></div>';
      chatArea.appendChild(el);
      currentAssistantBubble = el.querySelector('.bubble');
    }
    currentAssistantBubble.textContent += text;
    chatArea.scrollTop = chatArea.scrollHeight;
  }

  function addChatMeta(text) {
    const el = document.createElement('div');
    el.className = 'chat-msg assistant';
    el.innerHTML = '<div class="meta">' + escHtml(text) + '</div>';
    chatArea.appendChild(el);
    chatArea.scrollTop = chatArea.scrollHeight;
  }

  // --- Prompt ---
  let promptInFlight = false;
  async function sendPrompt(text) {
    if (!sessionId || !text.trim() || promptInFlight) return;
    promptInFlight = true;
    enablePrompt(false);
    addUserMessage(text.trim());
    promptInput.value = '';
    chatInput.value = '';
    try {
      const r = await api('POST', '/session/' + sessionId + '/prompt', {
        prompt: [{ type: 'text', text: text.trim() }]
      });
      if (r.ok) {
        addChatMeta('stopReason: ' + (r.data.stopReason || 'unknown'));
      } else {
        addChatMeta('Error: ' + (r.data.error || 'prompt failed (' + r.status + ')'));
      }
    } finally {
      promptInFlight = false;
      if (sessionId) enablePrompt(true);
    }
  }

  // --- Permission handling ---
  const pendingPerms = new Map();

  function handlePermissionRequest(data) {
    const req = data.data;
    const requestId = req?.requestId;
    if (!requestId) return;
    pendingPerms.set(requestId, req);
    renderPermissions();

    addChatMeta('Permission requested: ' + requestId);
  }

  function removePermission(requestId) {
    pendingPerms.delete(requestId);
    renderPermissions();
  }

  function renderPermissions() {
    if (pendingPerms.size === 0) {
      permissionPanel.style.display = 'none';
      return;
    }
    permissionPanel.style.display = 'block';
    permissionList.innerHTML = '';
    for (const [id, req] of pendingPerms) {
      const card = document.createElement('div');
      card.className = 'permission-card';

      const h4 = document.createElement('h4');
      h4.textContent = req.tool?.name || 'Permission';
      card.appendChild(h4);

      const idDiv = document.createElement('div');
      idDiv.style.cssText = 'font-size:11px;color:var(--text2);margin-bottom:6px';
      idDiv.textContent = id;
      card.appendChild(idDiv);

      // Show toolCall context (command, input, path, etc.) when available
      const tc = req.toolCall || req.tool;
      if (tc) {
        const detail = document.createElement('pre');
        detail.style.cssText = 'font-size:11px;color:var(--text2);margin-bottom:6px;white-space:pre-wrap;word-break:break-all;max-height:120px;overflow-y:auto;background:var(--bg);padding:6px;border-radius:4px;border:1px solid var(--border)';
        const parts = [];
        if (tc.command) parts.push('command: ' + tc.command);
        if (tc.input) parts.push('input: ' + (typeof tc.input === 'string' ? tc.input : JSON.stringify(tc.input, null, 2)));
        if (tc.path) parts.push('path: ' + tc.path);
        if (tc.diff) parts.push('diff: ' + tc.diff);
        if (tc.serverUrl) parts.push('url: ' + tc.serverUrl);
        if (parts.length === 0 && tc.name) parts.push('tool: ' + tc.name);
        if (parts.length > 0) {
          detail.textContent = parts.join('\\n');
          card.appendChild(detail);
        }
      }

      function makePermBtn(reqId, optId, label, isCancel) {
        const btn = document.createElement('button');
        btn.className = 'btn opt-btn';
        btn.textContent = label;
        btn.dataset.req = reqId;
        if (isCancel) {
          btn.dataset.cancel = '1';
          btn.style.borderColor = 'var(--err)';
          btn.style.color = 'var(--err)';
        } else {
          btn.dataset.opt = optId;
        }
        btn.addEventListener('click', async () => {
          let outcome;
          if (isCancel) {
            outcome = { outcome: 'cancelled' };
          } else {
            outcome = { outcome: 'selected', optionId: optId };
          }
          const result = await api('POST', '/permission/' + reqId, { outcome });
          if (result.ok) {
            removePermission(reqId);
          } else {
            logError('PERM-ERR', 'Failed to resolve permission ' + reqId + ': ' + JSON.stringify(result.data));
          }
        });
        return btn;
      }

      if (req.options && Array.isArray(req.options)) {
        for (const opt of req.options) {
          card.appendChild(makePermBtn(id, opt.optionId, opt.name || opt.optionId, false));
        }
      }
      card.appendChild(makePermBtn(id, null, 'Cancel', true));
      permissionList.appendChild(card);
    }
  }

  // --- Button bindings ---
  $('#btnCreateSession').addEventListener('click', createSession);
  $('#btnListSessions').addEventListener('click', async () => {
    const cwd = cwdInput.value.trim();
    if (!cwd) { alert('Enter a cwd first'); return; }
    await api('GET', '/workspace/' + encodeURIComponent(cwd) + '/sessions');
  });
  $('#btnSendPrompt').addEventListener('click', () => sendPrompt(promptInput.value));
  $('#btnChatSend').addEventListener('click', () => sendPrompt(chatInput.value));
  chatInput.addEventListener('keydown', (e) => {
    if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); sendPrompt(chatInput.value); }
  });
  promptInput.addEventListener('keydown', (e) => {
    if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); sendPrompt(promptInput.value); }
  });
  $('#btnCancel').addEventListener('click', async () => {
    if (!sessionId) return;
    await api('POST', '/session/' + sessionId + '/cancel', {});
  });
  $('#btnSetModel').addEventListener('click', async () => {
    if (!sessionId) return;
    const mid = modelInput.value.trim();
    if (!mid) { alert('Enter a model ID'); return; }
    await api('POST', '/session/' + sessionId + '/model', { modelId: mid });
  });
  $('#btnHealth').addEventListener('click', () => api('GET', '/health'));
  $('#btnHealthDeep').addEventListener('click', () => api('GET', '/health?deep=1'));
  $('#btnCaps').addEventListener('click', () => api('GET', '/capabilities'));

  // --- Init ---
  checkHealth();
})();
</script>
</body>
</html>`
  );
}
__name(getDemoHtml, "getDemoHtml");

// packages/cli/src/serve/routes/health-demo.ts
function createHealthDemoRoutes(deps) {
  const {
    opts,
    getPort,
    workspaceRegistry,
    getActiveSseCount: getActiveSseCount2,
    getRateLimiter
  } = deps;
  const demoHandler = /* @__PURE__ */ __name((_req, res) => {
    try {
      res.type("html").set("X-Frame-Options", "DENY").set(
        "Content-Security-Policy",
        "default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; connect-src 'self'; frame-ancestors 'none'"
      ).send(getDemoHtml(getPort()));
    } catch (err) {
      writeStderrLine(
        `qwen serve: /demo render failed: ${err instanceof Error ? err.message : String(err)}`
      );
      res.status(500).json({ error: "Failed to render demo page" });
    }
  }, "demoHandler");
  const healthHandler = /* @__PURE__ */ __name((req, res) => {
    if (!isDeepHealthQuery(req.query["deep"])) {
      res.status(200).json({ status: "ok" });
      return;
    }
    let failedWorkspaceId;
    try {
      const runtimes = workspaceRegistry.listManaged();
      let sessions = 0;
      let pendingPermissions = 0;
      let activePrompts = 0;
      let channelAlive = false;
      let lastActivity = null;
      for (const runtime of runtimes) {
        failedWorkspaceId = runtime.workspaceId;
        const bridge = runtime.bridge;
        const runtimeSessions = bridge.sessionCount;
        const runtimePendingPermissions = bridge.pendingPermissionCount;
        const runtimeActivePrompts = bridge.activePromptCount;
        const runtimeChannelAlive = bridge.isChannelLive();
        const runtimeLastActivity = bridge.lastActivityAt;
        sessions += runtimeSessions;
        pendingPermissions += runtimePendingPermissions;
        activePrompts += runtimeActivePrompts;
        channelAlive = channelAlive || runtimeChannelAlive;
        if (runtimeLastActivity !== null && (lastActivity === null || runtimeLastActivity > lastActivity)) {
          lastActivity = runtimeLastActivity;
        }
        failedWorkspaceId = void 0;
      }
      const now = Date.now();
      const rateLimiter = getRateLimiter();
      res.status(200).json({
        status: "ok",
        workspaceCount: runtimes.length,
        sessions,
        pendingPermissions,
        activePrompts,
        connectedClients: getActiveSseCount2(),
        channelAlive,
        lastActivityAt: lastActivity !== null ? new Date(lastActivity).toISOString() : null,
        idleSinceMs: lastActivity !== null ? now - lastActivity : null,
        ...rateLimiter ? { rateLimitHits: rateLimiter.getHitCounts() } : {}
      });
    } catch (err) {
      const workspaceContext = failedWorkspaceId !== void 0 ? ` for workspace ${JSON.stringify(failedWorkspaceId)}` : "";
      writeStderrLine(
        `qwen serve: /health deep probe failed${workspaceContext}: ${err instanceof Error ? err.message : String(err)}`
      );
      res.status(503).json({ status: "degraded", reason: "aggregation_failed" });
    }
  }, "healthHandler");
  const loopback = isLoopbackBind(opts.hostname);
  const exposeHealthPreAuth = loopback && !opts.requireAuth;
  return {
    exposeHealthPreAuth,
    register(app) {
      app.get("/health", healthHandler);
      app.get("/demo", demoHandler);
    }
  };
}
__name(createHealthDemoRoutes, "createHealthDemoRoutes");

// packages/cli/src/serve/routes/workspace-auth.ts
init_esbuild_shims();

// packages/cli/src/serve/server/auth-provider-helpers.ts
init_esbuild_shims();
import * as net from "node:net";
var AUTH_PROVIDER_STEPS = [
  "protocol",
  "baseUrl",
  "apiKey",
  "models",
  "advancedConfig"
];
function buildAuthProviderDescriptor(provider) {
  const steps = AUTH_PROVIDER_STEPS.filter(
    (step) => shouldShowStep(provider, step)
  );
  return {
    id: provider.id,
    label: provider.label,
    description: provider.description,
    ...provider.uiGroup ? { uiGroup: provider.uiGroup } : {},
    protocol: provider.protocol,
    ...provider.protocolOptions ? { protocolOptions: [...provider.protocolOptions] } : {},
    ...provider.baseUrl !== void 0 ? { baseUrl: provider.baseUrl } : {},
    ...typeof provider.envKey === "string" ? { envKey: provider.envKey } : {},
    ...provider.models ? {
      models: provider.models.map((model) => ({
        id: model.id,
        ...model.contextWindowSize !== void 0 ? { contextWindowSize: model.contextWindowSize } : {},
        ...model.enableThinking !== void 0 ? { enableThinking: model.enableThinking } : {},
        ...model.modalities ? { modalities: model.modalities } : {},
        ...model.description ? { description: model.description } : {}
      }))
    } : {},
    ...provider.modelsEditable !== void 0 ? { modelsEditable: provider.modelsEditable } : {},
    ...provider.apiKeyPlaceholder ? { apiKeyPlaceholder: provider.apiKeyPlaceholder } : {},
    ...typeof provider.documentationUrl === "string" ? { documentationUrl: provider.documentationUrl } : {},
    ...provider.showAdvancedConfig !== void 0 ? { showAdvancedConfig: provider.showAdvancedConfig } : {},
    ...provider.uiLabels ? { uiLabels: provider.uiLabels } : {},
    steps
  };
}
__name(buildAuthProviderDescriptor, "buildAuthProviderDescriptor");
function buildAuthProviderCatalog(workspaceCwd) {
  const providers = ALL_PROVIDERS.map(buildAuthProviderDescriptor);
  const providerIdsByGroup = /* @__PURE__ */ __name((group) => providers.filter((provider) => provider.uiGroup === group).map((provider) => provider.id), "providerIdsByGroup");
  return {
    v: 1,
    workspaceCwd,
    providers,
    groups: [
      {
        id: "alibaba",
        label: "Alibaba ModelStudio",
        description: "Official recommended setup: Coding Plan, Token Plan, or Standard API Key",
        providerIds: providerIdsByGroup("alibaba")
      },
      {
        id: "third-party",
        label: "Third-party Providers",
        description: "Choose a built-in provider and connect with an API key",
        providerIds: providerIdsByGroup("third-party")
      },
      {
        id: "custom",
        label: "Custom Provider",
        description: "Manually connect a local server, proxy, or unsupported provider",
        providerIds: providerIdsByGroup("custom")
      }
    ]
  };
}
__name(buildAuthProviderCatalog, "buildAuthProviderCatalog");
function parseStringArray2(value) {
  if (!Array.isArray(value)) return void 0;
  const result = value.map((item) => typeof item === "string" ? item.trim() : "").filter((item) => item.length > 0);
  return result.length > 0 ? [...new Set(result)] : void 0;
}
__name(parseStringArray2, "parseStringArray");
function parsePositiveBoundedInteger(value, max) {
  if (typeof value !== "number" || !Number.isInteger(value) || !Number.isFinite(value) || value <= 0 || value > max) {
    return void 0;
  }
  return value;
}
__name(parsePositiveBoundedInteger, "parsePositiveBoundedInteger");
function parseIPv4MappedHexSuffix(suffix) {
  const hexParts = suffix.split(":");
  if (hexParts.length !== 2) return void 0;
  const [hiRaw, loRaw] = hexParts;
  if (!/^[0-9a-f]{1,4}$/i.test(hiRaw) || !/^[0-9a-f]{1,4}$/i.test(loRaw)) {
    return void 0;
  }
  const hi = Number.parseInt(hiRaw, 16);
  const lo = Number.parseInt(loRaw, 16);
  return `${hi >> 8 & 255}.${hi & 255}.${lo >> 8 & 255}.${lo & 255}`;
}
__name(parseIPv4MappedHexSuffix, "parseIPv4MappedHexSuffix");
function parseIPv6FirstHextet(host) {
  const first = host.split(":", 1)[0];
  if (!first || !/^[0-9a-f]{1,4}$/i.test(first)) return void 0;
  return Number.parseInt(first, 16);
}
__name(parseIPv6FirstHextet, "parseIPv6FirstHextet");
function parseLegacyIPv4Part(value, max) {
  let parsed;
  if (/^0x[0-9a-f]+$/i.test(value)) {
    parsed = Number.parseInt(value.slice(2), 16);
  } else if (/^0[0-7]+$/.test(value)) {
    parsed = Number.parseInt(value, 8);
  } else if (/^[0-9]+$/.test(value)) {
    parsed = Number.parseInt(value, 10);
  } else {
    return void 0;
  }
  return parsed <= max ? parsed : void 0;
}
__name(parseLegacyIPv4Part, "parseLegacyIPv4Part");
function parseLegacyIPv4Host(host) {
  const parts = host.split(".");
  if (parts.length < 1 || parts.length > 4 || parts.some((part) => !part)) {
    return void 0;
  }
  const maxLastPart = [4294967295, 16777215, 65535, 255][parts.length - 1];
  if (maxLastPart === void 0) return void 0;
  const parsed = parts.map(
    (part, index) => parseLegacyIPv4Part(part, index === parts.length - 1 ? maxLastPart : 255)
  );
  if (parsed.some((part) => part === void 0)) return void 0;
  const values = parsed;
  const numeric = values.length === 1 ? values[0] : values.length === 2 ? values[0] * 16777216 + values[1] : values.length === 3 ? values[0] * 16777216 + values[1] * 65536 + values[2] : values[0] * 16777216 + values[1] * 65536 + values[2] * 256 + values[3];
  return [
    Math.floor(numeric / 16777216) & 255,
    Math.floor(numeric / 65536) & 255,
    Math.floor(numeric / 256) & 255,
    numeric & 255
  ].join(".");
}
__name(parseLegacyIPv4Host, "parseLegacyIPv4Host");
function isBlockedAuthProviderHost(hostname) {
  const stripped = hostname.endsWith(".") ? hostname.slice(0, -1) : hostname;
  const host = stripped.toLowerCase();
  if (host === "localhost" || host.endsWith(".localhost")) return true;
  const bareHost = host.startsWith("[") && host.endsWith("]") ? host.slice(1, -1) : host;
  const blocklistHost = parseLegacyIPv4Host(bareHost) ?? bareHost;
  const ipVersion = net.isIP(blocklistHost);
  if (ipVersion === 4) {
    const parts = blocklistHost.split(".").map((part) => Number(part));
    const [a, b] = parts;
    return a === 0 || a === 10 || a === 127 || a === 100 && b !== void 0 && b >= 64 && b <= 127 || a === 169 && b === 254 || a === 172 && b !== void 0 && b >= 16 && b <= 31 || a === 192 && b === 168;
  }
  if (ipVersion === 6) {
    if (blocklistHost === "::" || blocklistHost === "::1") return true;
    const firstHextet = parseIPv6FirstHextet(blocklistHost);
    if (firstHextet !== void 0 && (firstHextet >= 65152 && firstHextet <= 65215 || (firstHextet & 65024) === 64512)) {
      return true;
    }
    if (blocklistHost.startsWith("::ffff:")) {
      const suffix = blocklistHost.slice("::ffff:".length);
      if (net.isIP(suffix) === 4) {
        return isBlockedAuthProviderHost(suffix);
      }
      const mappedIPv4 = parseIPv4MappedHexSuffix(suffix);
      return mappedIPv4 ? isBlockedAuthProviderHost(mappedIPv4) : true;
    }
  }
  return false;
}
__name(isBlockedAuthProviderHost, "isBlockedAuthProviderHost");
function parseAuthProviderBaseUrl(value, allowPrivateBaseUrl) {
  if (value === void 0 || value === null) return void 0;
  if (typeof value !== "string") return null;
  const trimmed = value.trim();
  if (!trimmed) return void 0;
  let parsed;
  try {
    parsed = new URL(trimmed);
  } catch {
    return null;
  }
  if (parsed.protocol !== "http:" && parsed.protocol !== "https:") return null;
  if (parsed.username || parsed.password) return null;
  if (!allowPrivateBaseUrl && isBlockedAuthProviderHost(parsed.hostname)) {
    return null;
  }
  return parsed.toString().replace(/\/$/, "");
}
__name(parseAuthProviderBaseUrl, "parseAuthProviderBaseUrl");
function parseAuthProviderInstallRequest(body, options) {
  const providerId = body["providerId"];
  const apiKey = body["apiKey"];
  if (typeof providerId !== "string" || providerId.trim().length === 0 || typeof apiKey !== "string" || apiKey.trim().length === 0) {
    return {
      ok: false,
      code: "invalid_request",
      error: "`providerId` and `apiKey` are required"
    };
  }
  const protocol = body["protocol"];
  const baseUrl = parseAuthProviderBaseUrl(
    body["baseUrl"],
    options?.allowPrivateBaseUrl === true
  );
  if (baseUrl === null) {
    return {
      ok: false,
      code: "invalid_base_url",
      error: "`baseUrl` must be an http(s) URL without credentials or blocked private-network host"
    };
  }
  const modelIds = parseStringArray2(body["modelIds"]);
  const rawAdvanced = body["advancedConfig"] && typeof body["advancedConfig"] === "object" ? body["advancedConfig"] : void 0;
  const rawMultimodal = rawAdvanced?.["multimodal"] && typeof rawAdvanced["multimodal"] === "object" ? rawAdvanced["multimodal"] : void 0;
  const contextWindowSize = parsePositiveBoundedInteger(
    rawAdvanced?.["contextWindowSize"],
    1e7
  );
  const maxTokens = parsePositiveBoundedInteger(
    rawAdvanced?.["maxTokens"],
    1e7
  );
  const advancedConfig = rawAdvanced ? {
    ...typeof rawAdvanced["enableThinking"] === "boolean" ? { enableThinking: rawAdvanced["enableThinking"] } : {},
    ...rawMultimodal ? {
      multimodal: {
        ...typeof rawMultimodal["image"] === "boolean" ? { image: rawMultimodal["image"] } : {},
        ...typeof rawMultimodal["pdf"] === "boolean" ? { pdf: rawMultimodal["pdf"] } : {},
        ...typeof rawMultimodal["audio"] === "boolean" ? { audio: rawMultimodal["audio"] } : {},
        ...typeof rawMultimodal["video"] === "boolean" ? { video: rawMultimodal["video"] } : {}
      }
    } : {},
    ...contextWindowSize !== void 0 ? { contextWindowSize } : {},
    ...maxTokens !== void 0 ? { maxTokens } : {}
  } : void 0;
  return {
    ok: true,
    value: {
      providerId: providerId.trim(),
      ...typeof protocol === "string" && protocol.trim() ? {
        protocol: protocol.trim()
      } : {},
      ...baseUrl ? { baseUrl } : {},
      apiKey,
      ...modelIds ? { modelIds } : {},
      ...advancedConfig ? { advancedConfig } : {}
    }
  };
}
__name(parseAuthProviderInstallRequest, "parseAuthProviderInstallRequest");

// packages/cli/src/serve/routes/workspace-auth.ts
function callerIsDeviceFlowInitiator(view, callerClientId) {
  return view.initiatorClientId === void 0 && callerClientId === void 0 || view.initiatorClientId !== void 0 && callerClientId !== void 0 && callerClientId === view.initiatorClientId;
}
__name(callerIsDeviceFlowInitiator, "callerIsDeviceFlowInitiator");
function toDeviceFlowStartResponseBody(view, attached, callerClientId) {
  const body = {
    deviceFlowId: view.deviceFlowId,
    providerId: view.providerId,
    status: view.status,
    expiresAt: view.expiresAt ?? 0,
    intervalMs: view.intervalMs ?? 0,
    attached
  };
  if (callerIsDeviceFlowInitiator(view, callerClientId)) {
    body["userCode"] = view.userCode ?? "";
    body["verificationUri"] = view.verificationUri ?? "";
    if (view.verificationUriComplete) {
      body["verificationUriComplete"] = view.verificationUriComplete;
    }
  }
  if (view.initiatorClientId && callerClientId !== void 0 && callerClientId === view.initiatorClientId) {
    body["initiatorClientId"] = view.initiatorClientId;
  }
  return body;
}
__name(toDeviceFlowStartResponseBody, "toDeviceFlowStartResponseBody");
function toDeviceFlowStateBody(view, callerClientId) {
  const body = {
    deviceFlowId: view.deviceFlowId,
    providerId: view.providerId,
    status: view.status,
    createdAt: view.createdAt
  };
  if (view.errorKind) body["errorKind"] = view.errorKind;
  if (view.hint) body["hint"] = view.hint;
  if (view.expiresAt !== void 0) body["expiresAt"] = view.expiresAt;
  if (view.intervalMs !== void 0) body["intervalMs"] = view.intervalMs;
  if (view.lastPolledAt !== void 0) body["lastPolledAt"] = view.lastPolledAt;
  if (callerIsDeviceFlowInitiator(view, callerClientId)) {
    if (view.userCode) body["userCode"] = view.userCode;
    if (view.verificationUri) body["verificationUri"] = view.verificationUri;
    if (view.verificationUriComplete) {
      body["verificationUriComplete"] = view.verificationUriComplete;
    }
    if (view.initiatorClientId) {
      body["initiatorClientId"] = view.initiatorClientId;
    }
  }
  return body;
}
__name(toDeviceFlowStateBody, "toDeviceFlowStateBody");
function registerWorkspaceAuthRoutes(app, deps) {
  const {
    mutate,
    deviceFlowRegistry,
    getSupportedDeviceFlowProviders,
    sendBridgeError: sendBridgeError2,
    boundWorkspace,
    allowPrivateAuthBaseUrl,
    installAuthProvider
  } = deps;
  app.post(
    "/workspace/auth/device-flow",
    mutate({ strict: true }),
    async (req, res) => {
      const body = safeBody(req);
      const providerIdRaw = body["providerId"];
      if (typeof providerIdRaw !== "string" || providerIdRaw.length === 0) {
        res.status(400).json({
          error: "`providerId` must be a non-empty string",
          code: "invalid_request"
        });
        return;
      }
      const supportedProviders = getSupportedDeviceFlowProviders();
      if (!supportedProviders.includes(providerIdRaw)) {
        res.status(400).json({
          error: `Unsupported device-flow provider: ${providerIdRaw}`,
          code: "unsupported_provider",
          supportedProviders
        });
        return;
      }
      const providerId = providerIdRaw;
      const clientId = parseClientIdHeader(req, res);
      if (clientId === null) return;
      try {
        const { view, attached } = await deviceFlowRegistry.start({
          providerId,
          ...clientId !== void 0 ? { initiatorClientId: clientId } : {}
        });
        res.status(attached ? 200 : 201).json(toDeviceFlowStartResponseBody(view, attached, clientId));
      } catch (err) {
        if (err instanceof UnsupportedDeviceFlowProviderError) {
          res.status(400).json({ error: err.message, code: "unsupported_provider" });
          return;
        }
        if (err instanceof TooManyActiveDeviceFlowsError) {
          res.status(409).json({ error: err.message, code: "too_many_active_flows" });
          return;
        }
        if (err instanceof UpstreamDeviceFlowError) {
          res.status(502).json({ error: err.message, code: "upstream_error" });
          return;
        }
        sendBridgeError2(res, err, {
          route: "POST /workspace/auth/device-flow"
        });
      }
    }
  );
  app.get(
    "/workspace/auth/device-flow/:id",
    mutate({ strict: true }),
    async (req, res) => {
      const id = req.params["id"];
      if (!id) {
        res.status(404).json({
          error: "Device-flow id required",
          code: "device_flow_not_found"
        });
        return;
      }
      const view = deviceFlowRegistry.get(id);
      if (!view) {
        res.status(404).json({
          error: `Device-flow ${id} not found`,
          code: "device_flow_not_found"
        });
        return;
      }
      const clientId = parseClientIdHeader(req, res);
      if (clientId === null) return;
      if (!callerIsDeviceFlowInitiator(view, clientId) && isServeDebugMode()) {
        writeStderrLine(
          `qwen serve debug: GET /workspace/auth/device-flow/${id} redacted verification fields \u2014 caller-clientId mismatch (initiator=${view.initiatorClientId ?? "anonymous"}, caller=${clientId ?? "anonymous"})`
        );
      }
      res.status(200).json(toDeviceFlowStateBody(view, clientId));
    }
  );
  app.delete(
    "/workspace/auth/device-flow/:id",
    mutate({ strict: true }),
    (req, res) => {
      const id = req.params["id"];
      if (!id) {
        res.status(404).json({
          error: "Device-flow id required",
          code: "device_flow_not_found"
        });
        return;
      }
      const clientId = parseClientIdHeader(req, res);
      if (clientId === null) return;
      const result = deviceFlowRegistry.cancel(id, clientId);
      if (result === void 0) {
        res.status(404).json({
          error: `Device-flow ${id} not found`,
          code: "device_flow_not_found"
        });
        return;
      }
      res.status(204).end();
    }
  );
  app.get("/workspace/auth/status", (_req, res) => {
    const pending = deviceFlowRegistry.listPending();
    res.status(200).json({
      v: 1,
      workspaceCwd: boundWorkspace,
      providers: [],
      pendingDeviceFlows: pending.map((view) => ({
        deviceFlowId: view.deviceFlowId,
        providerId: view.providerId,
        ...view.expiresAt !== void 0 ? { expiresAt: view.expiresAt } : {}
      })),
      // Derive from runtime provider map (single source of truth).
      supportedDeviceFlowProviders: getSupportedDeviceFlowProviders()
    });
  });
  app.get("/workspace/auth/providers", (_req, res) => {
    res.status(200).json(buildAuthProviderCatalog(boundWorkspace));
  });
  app.post(
    "/workspace/auth/provider",
    mutate({ strict: true }),
    async (req, res) => {
      if (!installAuthProvider) {
        res.status(501).json({
          error: "Auth provider installation is not implemented by this daemon",
          code: "not_implemented"
        });
        return;
      }
      const parsed = parseAuthProviderInstallRequest(safeBody(req), {
        allowPrivateBaseUrl: allowPrivateAuthBaseUrl
      });
      if (!parsed.ok) {
        res.status(400).json({
          error: parsed.error,
          code: parsed.code
        });
        return;
      }
      const installRequest = parsed.value;
      const knownProvider = ALL_PROVIDERS.find(
        (provider) => provider.id === installRequest.providerId
      );
      if (!knownProvider) {
        res.status(400).json({
          error: `Unsupported auth provider: ${installRequest.providerId}`,
          code: "unsupported_provider"
        });
        return;
      }
      if (installRequest.protocol) {
        const allowedProtocols = knownProvider.protocolOptions && knownProvider.protocolOptions.length ? knownProvider.protocolOptions : [knownProvider.protocol];
        if (!allowedProtocols.includes(installRequest.protocol)) {
          res.status(400).json({
            error: `protocol must be one of: ${allowedProtocols.join(", ")}`,
            code: "unsupported_protocol"
          });
          return;
        }
      }
      try {
        res.status(200).json(await installAuthProvider(installRequest));
      } catch (err) {
        sendBridgeError2(res, err, {
          route: "POST /workspace/auth/provider",
          providerId: installRequest.providerId
        });
      }
    }
  );
}
__name(registerWorkspaceAuthRoutes, "registerWorkspaceAuthRoutes");

// packages/cli/src/serve/routes/workspace-extensions.ts
init_esbuild_shims();
import * as crypto2 from "node:crypto";

// packages/cli/src/serve/extension-operation-scheduler.ts
init_esbuild_shims();
function abortReason(signal) {
  return signal.reason ?? new DOMException("Aborted", "AbortError");
}
__name(abortReason, "abortReason");
function createFifoTaskQueue(limit) {
  if (!Number.isInteger(limit) || limit < 1) {
    throw new Error(
      `Task queue limit must be a positive integer, got ${limit}.`
    );
  }
  let active = 0;
  const queued = [];
  const pump = /* @__PURE__ */ __name(() => {
    while (active < limit && queued.length > 0) {
      const item = queued.shift();
      const removeAbortListener = item.removeAbortListener;
      item.removeAbortListener = void 0;
      removeAbortListener?.();
      if (item.signal?.aborted) {
        item.reject(abortReason(item.signal));
        continue;
      }
      active += 1;
      try {
        item.onStart?.();
      } catch (error2) {
        active -= 1;
        item.reject(error2);
        continue;
      }
      let released = false;
      const release = /* @__PURE__ */ __name(() => {
        if (released) return;
        released = true;
        active -= 1;
        pump();
      }, "release");
      Promise.resolve().then(() => item.task(release)).then(item.resolve, item.reject).finally(release);
    }
  }, "pump");
  const enqueue = /* @__PURE__ */ __name((task, options = {}) => new Promise((resolve5, reject) => {
    if (options.signal?.aborted) {
      reject(abortReason(options.signal));
      return;
    }
    const item = {
      task,
      ...options.signal ? { signal: options.signal } : {},
      ...options.onStart ? { onStart: options.onStart } : {},
      resolve: resolve5,
      reject
    };
    if (options.signal) {
      const onAbort = /* @__PURE__ */ __name(() => {
        const index = queued.indexOf(item);
        if (index < 0) return;
        queued.splice(index, 1);
        item.removeAbortListener?.();
        reject(abortReason(options.signal));
      }, "onAbort");
      options.signal.addEventListener("abort", onAbort, { once: true });
      item.removeAbortListener = () => options.signal?.removeEventListener("abort", onAbort);
    }
    queued.push(item);
    pump();
  }), "enqueue");
  const run = /* @__PURE__ */ __name((task, options) => enqueue(async () => await task(), options), "run");
  return { run, runUntilReleased: enqueue };
}
__name(createFifoTaskQueue, "createFifoTaskQueue");

// packages/cli/src/serve/routes/workspace-extensions-controller.ts
init_esbuild_shims();
import * as crypto from "node:crypto";
var MAX_UNFINISHED_EXTENSION_OPERATIONS = 10;
var sanitizeDaemonMessage = /* @__PURE__ */ __name((message) => redactUrlCredentials(stripAnsiAndControl(message)), "sanitizeDaemonMessage");
var redactExtensionDisplaySource = /* @__PURE__ */ __name((source) => {
  const redacted = redactUrlCredentials(source);
  if (/^[A-Za-z]:[\\/]/.test(redacted)) return redacted;
  try {
    const url = new URL(redacted);
    url.search = "";
    url.hash = "";
    return url.toString();
  } catch {
    return redacted;
  }
}, "redactExtensionDisplaySource");
var EXTENSION_PREPARATION_CONCURRENCY = 2;
var EXTENSION_REFRESH_TIMEOUT_MS = 3e4;
var RECONCILE_SLOW_MS = 3e4;
var EXTENSION_QUEUE_FULL_MESSAGE = "Extension operation queue is full";
function createExtensionsController(deps) {
  const { boundWorkspace, bridge, workspace } = deps;
  const maxExtensionOperationHistory = deps.maxExtensionOperationHistory ?? 100;
  const preparationQueue = createFifoTaskQueue(
    EXTENSION_PREPARATION_CONCURRENCY
  );
  const commitQueue = createFifoTaskQueue(1);
  let unfinishedOperationCount = 0;
  const acquireOperationSlot = /* @__PURE__ */ __name((res) => {
    if (unfinishedOperationCount >= MAX_UNFINISHED_EXTENSION_OPERATIONS) {
      res.status(429).json({
        error: EXTENSION_QUEUE_FULL_MESSAGE,
        code: "extension_queue_full"
      });
      return void 0;
    }
    unfinishedOperationCount += 1;
    let released = false;
    return () => {
      if (released) return;
      released = true;
      unfinishedOperationCount -= 1;
    };
  }, "acquireOperationSlot");
  const createExtensionManager = /* @__PURE__ */ __name((workspaceDir = boundWorkspace, trustedOverride, interactions) => new ExtensionManager({
    workspaceDir,
    isWorkspaceTrusted: trustedOverride ?? getWorkspaceTrustStatus(loadSettings(workspaceDir).merged, workspaceDir).effective.state === "trusted",
    requestConsent: /* @__PURE__ */ __name(() => Promise.resolve(), "requestConsent"),
    networkPolicy: "public",
    requestSetting: interactions?.requestSetting ?? (async (setting) => {
      throw new Error(
        `Extension setting "${setting.envVar}" requires interactive configuration and is not supported over the daemon install endpoint.`
      );
    }),
    requestChoicePlugin: interactions?.requestChoicePlugin ?? (async () => {
      throw new Error(
        "Marketplace plugin selection is not supported over the daemon install endpoint. Specify a plugin name in the source."
      );
    })
  }), "createExtensionManager");
  const validateExtensionMutationClient = /* @__PURE__ */ __name((req, res, opts = {}) => {
    const clientId = parseAndValidateWorkspaceClientId(
      req,
      res,
      opts.bridges ?? bridge
    );
    if (clientId === null) return false;
    if (clientId === void 0 && opts.requireClientId !== false) {
      res.status(400).json({
        error: "Missing X-Qwen-Client-Id header",
        code: "missing_client_id"
      });
      return false;
    }
    return true;
  }, "validateExtensionMutationClient");
  const extensionOperations = /* @__PURE__ */ new Map();
  const isTerminalExtensionOperation = /* @__PURE__ */ __name((operation) => operation.status !== "queued" && operation.status !== "running" && operation.status !== "waiting_for_input", "isTerminalExtensionOperation");
  const redactExtensionOperationResult = /* @__PURE__ */ __name((event) => ({
    ...event,
    ...event.source ? { source: redactExtensionDisplaySource(event.source) } : {}
  }), "redactExtensionOperationResult");
  const bridgeMutationEvent = /* @__PURE__ */ __name((event) => {
    const redacted = redactExtensionOperationResult(event);
    if (event.status === "checked" || event.status === "refreshed") {
      const { status: _status, states: _states, ...bridgeEvent } = redacted;
      return bridgeEvent;
    }
    return redacted;
  }, "bridgeMutationEvent");
  const pruneExtensionOperations = /* @__PURE__ */ __name(() => {
    const terminalCount = /* @__PURE__ */ __name(() => [...extensionOperations.values()].filter(isTerminalExtensionOperation).length, "terminalCount");
    while (terminalCount() > maxExtensionOperationHistory) {
      let evicted = false;
      for (const [id, storedOperation] of extensionOperations) {
        if (!isTerminalExtensionOperation(storedOperation)) continue;
        extensionOperations.delete(id);
        evicted = true;
        break;
      }
      if (!evicted) break;
    }
  }, "pruneExtensionOperations");
  const rememberExtensionOperation = /* @__PURE__ */ __name((operation) => {
    extensionOperations.set(operation.operationId, operation);
    pruneExtensionOperations();
  }, "rememberExtensionOperation");
  const updateExtensionOperation = /* @__PURE__ */ __name((operationId, patch) => {
    const current = extensionOperations.get(operationId);
    if (!current) return;
    extensionOperations.set(operationId, {
      ...current,
      ...patch,
      updatedAt: Date.now()
    });
    pruneExtensionOperations();
  }, "updateExtensionOperation");
  let extensionsStatusCache;
  const refreshExtensionsForAllSessions = /* @__PURE__ */ __name(async () => {
    const queueAbort = new AbortController();
    let releaseCommitLane;
    const refresh = commitQueue.runUntilReleased(
      async (release) => {
        releaseCommitLane = release;
        extensionsStatusCache = void 0;
        return await workspace.refreshExtensionsForAllSessions();
      },
      { signal: queueAbort.signal }
    );
    let timer;
    try {
      return await Promise.race([
        refresh,
        new Promise((_resolve, reject) => {
          timer = setTimeout(() => {
            const error2 = new Error(
              `extension refresh timed out after ${EXTENSION_REFRESH_TIMEOUT_MS}ms`
            );
            releaseCommitLane?.();
            queueAbort.abort(error2);
            reject(error2);
          }, EXTENSION_REFRESH_TIMEOUT_MS);
          timer.unref?.();
        })
      ]);
    } finally {
      if (timer) clearTimeout(timer);
    }
  }, "refreshExtensionsForAllSessions");
  const runQueuedExtensionMutation = /* @__PURE__ */ __name((operation, failureContext, res, run, options = {}) => {
    const releaseOperationSlot = acquireOperationSlot(res);
    if (!releaseOperationSlot) return;
    const operationId = crypto.randomUUID();
    const now = Date.now();
    rememberExtensionOperation({
      v: 1,
      operationId,
      operation,
      status: "queued",
      createdAt: now,
      updatedAt: now,
      ...failureContext.source ? { source: redactExtensionDisplaySource(failureContext.source) } : {},
      ...failureContext.name ? { name: failureContext.name } : {}
    });
    const operationBasePath = options.operationBasePath ?? "/workspace/extensions/operations";
    try {
      res.status(202).location(`${operationBasePath}/${operationId}`).set("Retry-After", "1").json({ accepted: true, operationId });
    } catch {
      extensionOperations.delete(operationId);
      releaseOperationSlot();
      return;
    }
    void (async () => {
      let deadline;
      let committedGeneration;
      let reconciliationReservation;
      let mutationEvent;
      const commitWarnings = [];
      const runReconciliation = /* @__PURE__ */ __name(async (task) => {
        const reservation = reconciliationReservation;
        reconciliationReservation = void 0;
        return reservation ? await reservation.run(task) : await task();
      }, "runReconciliation");
      try {
        updateExtensionOperation(operationId, {
          status: "running",
          phase: "preparing"
        });
        const extensionManager = options.manager ?? options.createManager?.(operationId) ?? createExtensionManager();
        const deadlineController = new AbortController();
        let deadlineStarted = false;
        const startDeadline = /* @__PURE__ */ __name(() => {
          if (deadlineStarted) return;
          deadlineStarted = true;
          if (options.deadlineMs) {
            deadline = setTimeout(() => {
              const error2 = new Error(
                `Extension ${operation} exceeded its ${options.deadlineMs}ms preparation deadline.`
              );
              error2.code = "extension_prepare_timeout";
              deadlineController.abort(error2);
            }, options.deadlineMs);
            deadline.unref?.();
          }
        }, "startDeadline");
        let pendingPreparations = 0;
        let activePreparations = 0;
        const updatePreparationState = /* @__PURE__ */ __name(() => {
          if (activePreparations > 0) {
            updateExtensionOperation(operationId, {
              status: "running",
              phase: "preparing"
            });
          } else if (pendingPreparations > 0) {
            updateExtensionOperation(operationId, {
              status: "queued",
              phase: void 0
            });
          }
        }, "updatePreparationState");
        const context = {
          prepare: /* @__PURE__ */ __name(async (task) => {
            pendingPreparations += 1;
            let started = false;
            updatePreparationState();
            try {
              const prepared = await preparationQueue.run(
                async () => {
                  try {
                    return await task(deadlineController.signal);
                  } finally {
                    activePreparations -= 1;
                    updatePreparationState();
                  }
                },
                {
                  signal: deadlineController.signal,
                  onStart: /* @__PURE__ */ __name(() => {
                    startDeadline();
                    started = true;
                    pendingPreparations -= 1;
                    activePreparations += 1;
                    updatePreparationState();
                  }, "onStart")
                }
              );
              deadlineController.signal.throwIfAborted();
              return prepared;
            } catch (error2) {
              if (!started) {
                pendingPreparations -= 1;
                updatePreparationState();
              }
              if (deadlineController.signal.aborted) {
                throw deadlineController.signal.reason;
              }
              throw error2;
            }
          }, "prepare"),
          commit: /* @__PURE__ */ __name(async (task) => {
            updateExtensionOperation(operationId, {
              status: "running",
              phase: "committing"
            });
            const result = await commitQueue.runUntilReleased(
              async (release) => await task((generation) => {
                reconciliationReservation ??= options.reserveRuntimeReconciliation?.();
                committedGeneration = generation;
                release();
              })
            );
            if (committedGeneration === void 0) {
              reconciliationReservation ??= options.reserveRuntimeReconciliation?.();
              committedGeneration = result.generation;
            }
            for (const warning of result.warnings ?? []) {
              commitWarnings.push({
                workspaceCwd: boundWorkspace,
                code: warning.code,
                error: sanitizeDaemonMessage(warning.error).slice(0, 500)
              });
            }
            return result;
          }, "commit")
        };
        await extensionManager.refreshCache();
        const event = await run(
          extensionManager,
          deadlineController.signal,
          context,
          operationId
        );
        mutationEvent = event;
        if (deadline) clearTimeout(deadline);
        extensionsStatusCache = void 0;
        if (options.skipRefresh || event.updated === false) {
          reconciliationReservation?.release();
          reconciliationReservation = void 0;
          updateExtensionOperation(operationId, {
            status: commitWarnings.length > 0 ? "succeeded_with_warnings" : "succeeded",
            phase: void 0,
            result: redactExtensionOperationResult(event),
            ...commitWarnings.length > 0 ? { warnings: commitWarnings } : {}
          });
          return;
        }
        if (committedGeneration === void 0) {
          committedGeneration = (await extensionManager.getExtensionStoreSnapshot()).generation;
          reconciliationReservation ??= options.reserveRuntimeReconciliation?.();
        }
        updateExtensionOperation(operationId, {
          status: "running",
          phase: "reconciling"
        });
        const refreshTargets = typeof options.refreshRuntimes === "function" ? options.refreshRuntimes() : options.refreshRuntimes;
        if (refreshTargets) {
          const results = await runReconciliation(
            async () => await Promise.all(
              refreshTargets.map(async (runtime) => {
                const startedAt = Date.now();
                try {
                  runtime.workspaceService.invalidateWorkspaceSkillsStatus();
                  return {
                    status: "fulfilled",
                    result: await runtime.bridge.refreshExtensionsForAllSessions(
                      bridgeMutationEvent(event)
                    ),
                    elapsedMs: Date.now() - startedAt
                  };
                } catch (reason) {
                  return {
                    status: "rejected",
                    reason,
                    elapsedMs: Date.now() - startedAt
                  };
                }
              })
            )
          );
          let refreshed = 0;
          let failed = 0;
          const warnings = [
            ...commitWarnings
          ];
          for (let index = 0; index < results.length; index += 1) {
            const settled = results[index];
            const runtime = refreshTargets[index];
            if (settled.status === "fulfilled") {
              refreshed += settled.result.refreshed;
              failed += settled.result.failed;
              if (settled.result.failed > 0) {
                warnings.push({
                  workspaceId: runtime.workspaceId,
                  workspaceCwd: runtime.workspaceCwd,
                  error: `${settled.result.failed} session refresh(es) failed`
                });
              } else {
                options.onRuntimeReconciled?.(runtime, committedGeneration);
              }
            } else {
              failed += 1;
              const message = sanitizeDaemonMessage(
                settled.reason instanceof Error ? settled.reason.message : String(settled.reason)
              );
              warnings.push({
                workspaceId: runtime.workspaceId,
                workspaceCwd: runtime.workspaceCwd,
                error: message.slice(0, 500)
              });
              try {
                runtime.bridge.broadcastExtensionsChanged({
                  ...bridgeMutationEvent(event),
                  refreshed: 0,
                  failed: 1,
                  error: message.slice(0, 500)
                });
              } catch {
              }
            }
            if (settled.elapsedMs > RECONCILE_SLOW_MS) {
              warnings.push({
                workspaceId: runtime.workspaceId,
                workspaceCwd: runtime.workspaceCwd,
                code: "reconcile_slow",
                error: `Runtime reconciliation took ${settled.elapsedMs}ms.`
              });
            }
          }
          updateExtensionOperation(operationId, {
            status: warnings.length > 0 ? "succeeded_with_warnings" : "succeeded",
            phase: void 0,
            result: {
              ...redactExtensionOperationResult(event),
              refreshed,
              failed
            },
            ...warnings.length > 0 ? { warnings } : {}
          });
        } else {
          try {
            const { result, elapsedMs } = await runReconciliation(async () => {
              workspace.invalidateWorkspaceSkillsStatus();
              const startedAt = Date.now();
              const result2 = await bridge.refreshExtensionsForAllSessions(
                bridgeMutationEvent(event)
              );
              return { result: result2, elapsedMs: Date.now() - startedAt };
            });
            const warnings = [...commitWarnings];
            if (result.failed > 0) {
              warnings.push({
                workspaceCwd: boundWorkspace,
                error: `${result.failed} session refresh(es) failed`
              });
            }
            if (elapsedMs > RECONCILE_SLOW_MS) {
              warnings.push({
                workspaceCwd: boundWorkspace,
                code: "reconcile_slow",
                error: `Runtime reconciliation took ${elapsedMs}ms.`
              });
            }
            updateExtensionOperation(operationId, {
              status: warnings.length > 0 ? "succeeded_with_warnings" : "succeeded",
              phase: void 0,
              result: {
                ...redactExtensionOperationResult(event),
                refreshed: result.refreshed,
                failed: result.failed
              },
              ...warnings.length > 0 ? { warnings } : {}
            });
            writeStderrLine(
              `qwen serve: [${boundWorkspace}] extensions ${operation}: refreshed ${result.refreshed} session(s), ${result.failed} failed`
            );
          } catch (refreshErr) {
            const message = sanitizeDaemonMessage(
              refreshErr instanceof Error ? refreshErr.message : String(refreshErr)
            );
            updateExtensionOperation(operationId, {
              status: "succeeded_with_warnings",
              phase: void 0,
              result: {
                ...redactExtensionOperationResult(event),
                refreshed: 0,
                failed: 1,
                error: message.slice(0, 500)
              },
              warnings: [
                ...commitWarnings,
                {
                  workspaceCwd: boundWorkspace,
                  error: message.slice(0, 500)
                }
              ]
            });
            try {
              bridge.broadcastExtensionsChanged({
                ...bridgeMutationEvent(event),
                refreshed: 0,
                failed: 1,
                error: message.slice(0, 500)
              });
            } catch (broadcastErr) {
              writeStderrLine(
                `qwen serve: [${boundWorkspace}] extensions ${operation}: failed to broadcast refresh failure: ${sanitizeDaemonMessage(
                  broadcastErr instanceof Error ? broadcastErr.message : String(broadcastErr)
                )}`
              );
            }
            writeStderrLine(
              `qwen serve: [${boundWorkspace}] extensions ${operation}: mutation succeeded but refresh failed: ${message}`
            );
          }
        }
      } catch (err) {
        const message = sanitizeDaemonMessage(
          err instanceof Error ? err.message : String(err)
        );
        const code = err && typeof err === "object" && typeof err.code === "string" ? err.code : void 0;
        if (committedGeneration !== void 0) {
          extensionsStatusCache = void 0;
          const error2 = `Commit succeeded but post-commit work failed: ${message}`.slice(
            0,
            500
          );
          const warnings = [
            ...commitWarnings,
            {
              workspaceCwd: boundWorkspace,
              code: "post_commit_failed",
              error: error2
            }
          ];
          try {
            workspace.invalidateWorkspaceSkillsStatus();
          } catch (invalidationError) {
            warnings.push({
              workspaceCwd: boundWorkspace,
              code: "status_invalidation_failed",
              error: sanitizeDaemonMessage(
                invalidationError instanceof Error ? invalidationError.message : String(invalidationError)
              ).slice(0, 500)
            });
          }
          updateExtensionOperation(operationId, {
            status: "succeeded_with_warnings",
            phase: void 0,
            ...mutationEvent ? { result: redactExtensionOperationResult(mutationEvent) } : {},
            warnings
          });
          try {
            bridge.broadcastExtensionsChanged({
              ...mutationEvent ? bridgeMutationEvent(mutationEvent) : {
                ...failureContext.source ? {
                  source: redactExtensionDisplaySource(
                    failureContext.source
                  )
                } : {},
                ...failureContext.name ? { name: failureContext.name } : {}
              },
              refreshed: 0,
              failed: 1,
              error: error2
            });
          } catch {
          }
          try {
            writeStderrLine(
              `qwen serve: [${boundWorkspace}] extensions ${operation}: ${error2}`
            );
          } catch {
          }
          return;
        }
        updateExtensionOperation(operationId, {
          status: "failed",
          phase: void 0,
          interaction: void 0,
          error: message.slice(0, 500),
          ...code ? { code } : {}
        });
        try {
          bridge.broadcastExtensionsChanged({
            status: "failed",
            ...failureContext.source ? { source: redactExtensionDisplaySource(failureContext.source) } : {},
            ...failureContext.name ? { name: failureContext.name } : {},
            refreshed: 0,
            failed: 0,
            error: message.slice(0, 500)
          });
        } catch (broadcastErr) {
          writeStderrLine(
            `qwen serve: [${boundWorkspace}] extensions ${operation}: failed to broadcast failure: ${sanitizeDaemonMessage(
              broadcastErr instanceof Error ? broadcastErr.message : String(broadcastErr)
            )}`
          );
        }
        try {
          writeStderrLine(
            `qwen serve: [${boundWorkspace}] extensions ${operation}: background task failed: ${message}`
          );
        } catch {
        }
      } finally {
        if (deadline) clearTimeout(deadline);
        reconciliationReservation?.release();
        options.onSettled?.(operationId);
        releaseOperationSlot();
      }
    })();
  }, "runQueuedExtensionMutation");
  const buildLocalExtensionsStatus = /* @__PURE__ */ __name(async () => {
    const now = Date.now();
    if (extensionsStatusCache && extensionsStatusCache.expiresAt > now) {
      return extensionsStatusCache.value;
    }
    const extensionManager = createExtensionManager();
    await extensionManager.refreshCache();
    const entries = extensionManager.getLoadedExtensions().map((ext) => {
      const capabilities = {
        mcpServerCount: ext.mcpServers ? Object.keys(ext.mcpServers).length : 0,
        skillCount: ext.skills?.length ?? 0,
        agentCount: ext.agents?.length ?? 0,
        hookCount: ext.hooks ? Object.values(ext.hooks).reduce(
          (sum, defs) => sum + (defs?.length ?? 0),
          0
        ) : 0,
        commandCount: ext.commands?.length ?? 0,
        contextFileCount: ext.contextFiles.length,
        channelCount: ext.channels ? Object.keys(ext.channels).length : 0,
        hasSettings: (ext.settings?.length ?? 0) > 0
      };
      return {
        kind: "extension",
        id: ext.id,
        name: ext.name,
        ...ext.displayName ? { displayName: ext.displayName } : {},
        ...ext.config.description ? { description: ext.config.description } : {},
        version: ext.version,
        isActive: ext.isActive,
        path: ext.path,
        ...ext.installMetadata?.source ? {
          source: redactExtensionDisplaySource(
            ext.installMetadata.source
          )
        } : {},
        ...ext.installMetadata?.type ? { installType: ext.installMetadata.type } : {},
        ...ext.installMetadata?.originSource ? { originSource: ext.installMetadata.originSource } : {},
        ...ext.installMetadata?.ref ? { ref: ext.installMetadata.ref } : {},
        ...ext.installMetadata?.autoUpdate !== void 0 ? { autoUpdate: ext.installMetadata.autoUpdate } : {},
        updateState: ext.installMetadata ? "unknown" : "not updatable",
        capabilities,
        details: {
          mcpServers: ext.mcpServers ? Object.keys(ext.mcpServers) : [],
          commands: ext.commands ?? [],
          skills: ext.skills?.map((skill) => skill.name) ?? [],
          agents: ext.agents?.map((agent) => agent.name) ?? [],
          contextFiles: ext.contextFiles,
          settings: ext.resolvedSettings?.map((setting) => setting.name) ?? []
        }
      };
    });
    const status = {
      v: STATUS_SCHEMA_VERSION,
      workspaceCwd: boundWorkspace,
      initialized: true,
      extensions: entries
    };
    extensionsStatusCache = {
      expiresAt: Date.now() + 2e3,
      value: status
    };
    return status;
  }, "buildLocalExtensionsStatus");
  return {
    boundWorkspace,
    workspace,
    createExtensionManager,
    buildLocalExtensionsStatus,
    refreshExtensionsForAllSessions,
    getOperation: /* @__PURE__ */ __name((operationId) => extensionOperations.get(operationId), "getOperation"),
    getActiveOperations: /* @__PURE__ */ __name(() => [...extensionOperations.values()].filter(
      (operation) => !isTerminalExtensionOperation(operation)
    ), "getActiveOperations"),
    updateOperation: updateExtensionOperation,
    preparationQueue,
    acquireOperationSlot,
    validateExtensionMutationClient,
    runQueuedExtensionMutation
  };
}
__name(createExtensionsController, "createExtensionsController");

// packages/cli/src/serve/routes/workspace-extensions.ts
var EXTENSION_PREPARE_DEADLINE_MS = 10 * 6e4;
var EXTENSION_INTERACTION_DEADLINE_MS = 10 * 6e4;
var EXTENSION_INTERACTIVE_PREPARE_DEADLINE_MS = EXTENSION_PREPARE_DEADLINE_MS + EXTENSION_INTERACTION_DEADLINE_MS;
var EXTENSION_UPDATE_CHECK_DEADLINE_MS = 2 * 6e4;
var parseExtensionScope = /* @__PURE__ */ __name((body, res) => {
  const scope = body["scope"];
  if (scope !== "user" && scope !== "workspace") {
    res.status(400).json({ error: '`scope` must be either "user" or "workspace"' });
    return null;
  }
  return scope === "user" ? "User" /* User */ : "Workspace" /* Workspace */;
}, "parseExtensionScope");
var parseExtensionRegistryUrl = /* @__PURE__ */ __name((value, res) => {
  let parsed;
  try {
    parsed = new URL(value);
  } catch {
    res.status(400).json({ error: "`registry` must be a valid URL" });
    return null;
  }
  if (parsed.protocol !== "https:") {
    res.status(400).json({ error: "`registry` must use https" });
    return null;
  }
  if (parsed.username || parsed.password) {
    res.status(400).json({ error: "`registry` must not include credentials" });
    return null;
  }
  if (isBlockedAuthProviderHost(parsed.hostname)) {
    res.status(400).json({ error: "`registry` host is not allowed" });
    return null;
  }
  return parsed.toString().replace(/\/$/, "");
}, "parseExtensionRegistryUrl");
var parsePotentialSourceUrl = /* @__PURE__ */ __name((source) => {
  if (/^[a-zA-Z]:[\\/]/.test(source)) return null;
  try {
    return new URL(source);
  } catch {
    const colonIndex = source.indexOf(":");
    if (colonIndex >= 0 && source.slice(0, colonIndex).includes("/")) {
      return null;
    }
    const sshMatch = /^(?:[^@]+@)?(\[[^\]]+\]|[^:]+):/.exec(source);
    if (!sshMatch?.[1]) return null;
    try {
      return new URL(`ssh://${sshMatch[1]}`);
    } catch {
      return null;
    }
  }
}, "parsePotentialSourceUrl");
var validateExtensionSourceHost = /* @__PURE__ */ __name((source, res) => {
  const parsed = parsePotentialSourceUrl(source);
  if (!parsed) return true;
  if (parsed.username || parsed.password) {
    res.status(400).json({ error: "`source` must not include credentials" });
    return false;
  }
  if (isBlockedAuthProviderHost(parsed.hostname)) {
    res.status(400).json({ error: "`source` host is not allowed" });
    return false;
  }
  if (parsed.protocol !== "https:") {
    res.status(400).json({ error: "`source` must use https" });
    return false;
  }
  return true;
}, "validateExtensionSourceHost");
var validateExtensionSourceMetadata = /* @__PURE__ */ __name((installMetadata) => {
  if (installMetadata.type !== "git") return true;
  const parsed = parsePotentialSourceUrl(installMetadata.source);
  return !!parsed && (installMetadata.networkPolicy === "public" ? parsed.protocol === "https:" : parsed.protocol === "https:" || parsed.protocol === "ssh:") && !isBlockedAuthProviderHost(parsed.hostname);
}, "validateExtensionSourceMetadata");
var findLoadedExtension = /* @__PURE__ */ __name((extensionManager, extensionName) => {
  const requested = extensionName.toLowerCase();
  const extensions = extensionManager.getLoadedExtensions();
  const byName = extensions.find(
    (extension) => extension.name.toLowerCase() === requested
  );
  if (byName) return byName;
  if (!extensionName.includes("://") && !extensionName.includes("@")) {
    return void 0;
  }
  return extensions.find(
    (extension) => extension.installMetadata?.source?.toLowerCase() === requested
  );
}, "findLoadedExtension");
function registerWorkspaceExtensionRoutes(app, deps) {
  const {
    boundWorkspace,
    bridge,
    workspace,
    mutate,
    safeBody: safeBody2,
    sendBridgeError: sendBridgeError2,
    workspaceRegistry
  } = deps;
  const maxExtensionOperationHistory = deps.maxExtensionOperationHistory;
  const controllerDeps = /* @__PURE__ */ __name((ws, wsBridge, wsService) => ({
    boundWorkspace: ws,
    bridge: wsBridge,
    workspace: wsService,
    ...maxExtensionOperationHistory === void 0 ? {} : { maxExtensionOperationHistory }
  }), "controllerDeps");
  const primaryController = createExtensionsController(
    controllerDeps(boundWorkspace, bridge, workspace)
  );
  const pendingExtensionInteractions = /* @__PURE__ */ new Map();
  const supersededInstallOperations = /* @__PURE__ */ new Set();
  const cancelPendingExtensionInteraction = /* @__PURE__ */ __name((operationId, reason) => {
    const pending = pendingExtensionInteractions.get(operationId);
    if (!pending) return;
    clearTimeout(pending.timeout);
    pendingExtensionInteractions.delete(operationId);
    pending.reject(new Error(reason));
  }, "cancelPendingExtensionInteraction");
  const supersedeActiveInstallOperations = /* @__PURE__ */ __name((controller, currentOperationId) => {
    for (const operation of controller.getActiveOperations()) {
      if (operation.operation !== "install" || operation.operationId === currentOperationId) {
        continue;
      }
      supersededInstallOperations.add(operation.operationId);
      cancelPendingExtensionInteraction(
        operation.operationId,
        "Extension installation cancelled by a new install request"
      );
    }
  }, "supersedeActiveInstallOperations");
  const waitForExtensionInteraction = /* @__PURE__ */ __name((controller, operationId, interaction) => {
    if (supersededInstallOperations.delete(operationId)) {
      return Promise.reject(
        new Error("Extension installation superseded by a new install request")
      );
    }
    const operation = controller.getOperation(operationId);
    if (operation && operation.status !== "queued" && operation.status !== "running" && operation.status !== "waiting_for_input") {
      return Promise.reject(new Error("Extension operation already completed"));
    }
    const pendingInteraction = {
      ...interaction,
      id: crypto2.randomUUID()
    };
    return new Promise((resolve5, reject) => {
      const timeout = setTimeout(() => {
        pendingExtensionInteractions.delete(operationId);
        controller.updateOperation(operationId, {
          status: "failed",
          phase: void 0,
          interaction: void 0,
          error: "Extension interaction timed out"
        });
        reject(new Error("Extension interaction timed out"));
      }, EXTENSION_INTERACTION_DEADLINE_MS);
      timeout.unref?.();
      pendingExtensionInteractions.set(operationId, {
        interaction: pendingInteraction,
        resolve: resolve5,
        reject,
        timeout
      });
      controller.updateOperation(operationId, {
        status: "waiting_for_input",
        phase: void 0,
        interaction: pendingInteraction
      });
    });
  }, "waitForExtensionInteraction");
  const extensionInteractionHandlers = /* @__PURE__ */ __name((controller, operationId) => ({
    requestSetting: /* @__PURE__ */ __name((setting) => waitForExtensionInteraction(controller, operationId, {
      kind: "setting",
      setting: {
        name: setting.name,
        description: setting.description,
        sensitive: setting.sensitive === true
      }
    }), "requestSetting"),
    requestChoicePlugin: /* @__PURE__ */ __name((marketplace) => {
      if (marketplace.plugins.length === 0) {
        return Promise.reject(
          new Error(`Marketplace "${marketplace.name}" has no plugins`)
        );
      }
      return waitForExtensionInteraction(controller, operationId, {
        kind: "marketplace_plugin",
        marketplace: { name: marketplace.name },
        plugins: marketplace.plugins.map((plugin) => ({
          name: plugin.name,
          ...plugin.description ? { description: plugin.description } : {},
          source: redactExtensionDisplaySource(
            typeof plugin.source === "string" ? plugin.source : plugin.source.source === "github" ? plugin.source.repo : plugin.source.url
          ),
          ...plugin.category ? { category: plugin.category } : {},
          ...plugin.tags ? { tags: plugin.tags } : {}
        }))
      });
    }, "requestChoicePlugin")
  }), "extensionInteractionHandlers");
  const runtimeReconciliationQueue = createFifoTaskQueue(1);
  const reserveRuntimeReconciliation = /* @__PURE__ */ __name(() => {
    let provideTask;
    const task = new Promise(
      (resolve5) => {
        provideTask = resolve5;
      }
    );
    const queued = runtimeReconciliationQueue.run(async () => {
      const run = await task;
      return run ? await run() : void 0;
    });
    let used = false;
    return {
      run: /* @__PURE__ */ __name(async (run) => {
        if (used) throw new Error("Runtime reconciliation already released");
        used = true;
        provideTask(run);
        return await queued;
      }, "run"),
      release: /* @__PURE__ */ __name(() => {
        if (used) return;
        used = true;
        provideTask(void 0);
      }, "release")
    };
  }, "reserveRuntimeReconciliation");
  const appliedGenerationByWorkspaceId = /* @__PURE__ */ new Map();
  const onRuntimeReconciled = /* @__PURE__ */ __name((runtime, generation) => {
    appliedGenerationByWorkspaceId.set(runtime.workspaceId, generation);
  }, "onRuntimeReconciled");
  const globalReconciliationOptions = /* @__PURE__ */ __name(() => workspaceRegistry ? {
    refreshRuntimes: /* @__PURE__ */ __name(() => workspaceRegistry.list(), "refreshRuntimes"),
    reserveRuntimeReconciliation,
    onRuntimeReconciled
  } : {}, "globalReconciliationOptions");
  const workspaceReconciliationOptions = /* @__PURE__ */ __name(() => workspaceRegistry ? {
    refreshRuntimes: [workspaceRegistry.primary],
    reserveRuntimeReconciliation,
    onRuntimeReconciled
  } : {}, "workspaceReconciliationOptions");
  const mutationClientBridges = /* @__PURE__ */ __name((runtimes) => (typeof runtimes === "function" ? runtimes() : runtimes ?? workspaceRegistry?.list())?.map((runtime) => runtime.bridge) ?? [bridge], "mutationClientBridges");
  if (workspaceRegistry) {
    let observedGeneration;
    let reconciling = false;
    const reconcileExternalGeneration = /* @__PURE__ */ __name(async () => {
      if (reconciling) return;
      reconciling = true;
      try {
        const manager = primaryController.createExtensionManager(
          boundWorkspace,
          true
        );
        const generation = (await manager.getExtensionStoreSnapshot()).generation;
        const pendingRuntimes = workspaceRegistry.list().filter(
          (runtime) => (appliedGenerationByWorkspaceId.get(runtime.workspaceId) ?? 0) !== generation
        );
        if (generation === observedGeneration && pendingRuntimes.length === 0)
          return;
        const runtimes = pendingRuntimes;
        if (runtimes.length === 0) return;
        const results = await runtimeReconciliationQueue.run(
          async () => await Promise.allSettled(
            runtimes.map(async (runtime) => {
              runtime.workspaceService.invalidateWorkspaceSkillsStatus();
              const result = await runtime.bridge.refreshExtensionsForAllSessions();
              if (result.failed > 0) {
                throw new Error(
                  `${result.failed} extension session refresh(es) failed`
                );
              }
            })
          )
        );
        results.forEach((result, index) => {
          if (result.status === "fulfilled") {
            const workspaceId = runtimes[index].workspaceId;
            appliedGenerationByWorkspaceId.set(workspaceId, generation);
          } else {
            writeStderrLine(
              `qwen serve: extension generation reconciliation failed for workspace ${runtimes[index].workspaceId}: ${redactUrlCredentials(
                result.reason instanceof Error ? result.reason.message : String(result.reason)
              )}`
            );
          }
        });
        if (runtimes.length === pendingRuntimes.length && results.every((result) => result.status === "fulfilled")) {
          observedGeneration = generation;
        }
      } catch (error2) {
        writeStderrLine(
          `qwen serve: extension generation reconciliation failed: ${redactUrlCredentials(
            error2 instanceof Error ? error2.message : String(error2)
          )}`
        );
      } finally {
        reconciling = false;
      }
    }, "reconcileExternalGeneration");
    const generationPoller = setInterval(
      () => void reconcileExternalGeneration(),
      3e4
    );
    generationPoller.unref();
    app.locals.stopExtensionGenerationReconciler = () => clearInterval(generationPoller);
  }
  const registerFor = /* @__PURE__ */ __name((base, resolve5) => {
    app.get(base, async (req, res) => {
      const ctrl = resolve5(req, res, false);
      if (!ctrl) return;
      try {
        res.status(200).json(await ctrl.buildLocalExtensionsStatus());
      } catch (err) {
        sendBridgeError2(res, err, { route: `GET ${base}` });
      }
    });
    app.get(`${base}/operations`, async (req, res) => {
      const ctrl = resolve5(req, res, false);
      if (!ctrl) return;
      res.status(200).json({ v: 1, operations: ctrl.getActiveOperations() });
    });
    app.get(`${base}/operations/:operationId`, async (req, res) => {
      const ctrl = resolve5(req, res, false);
      if (!ctrl) return;
      try {
        const operationId = req.params["operationId"];
        if (!operationId) {
          res.status(400).json({ error: "Missing extension operation id" });
          return;
        }
        const operation = ctrl.getOperation(operationId);
        if (!operation) {
          res.status(404).json({
            error: `Extension operation "${operationId}" not found`,
            code: "extension_operation_not_found"
          });
          return;
        }
        if (base === "/workspace/extensions" && operation.status === "succeeded_with_warnings") {
          const warningError = operation.warnings?.find((warning) => warning.code === void 0)?.error ?? operation.warnings?.[0]?.error ?? operation.result?.error;
          const legacyOperation = {
            ...operation,
            status: "succeeded_with_refresh_error"
          };
          if (operation.result && warningError) {
            legacyOperation.result = {
              ...operation.result,
              error: warningError
            };
          } else if (warningError) {
            legacyOperation.error = warningError;
          }
          res.status(200).json(legacyOperation);
          return;
        }
        res.status(200).json(operation);
      } catch (err) {
        sendBridgeError2(res, err, {
          route: `GET ${base}/operations/:operationId`
        });
      }
    });
    app.post(
      `${base}/operations/:operationId/interactions/:interactionId`,
      mutate({ strict: true }),
      async (req, res) => {
        const ctrl = resolve5(req, res, false);
        if (!ctrl) return;
        try {
          if (!ctrl.validateExtensionMutationClient(req, res, {
            requireClientId: false
          })) {
            return;
          }
          const operationId = req.params["operationId"];
          const interactionId = req.params["interactionId"];
          const pending = operationId ? pendingExtensionInteractions.get(operationId) : void 0;
          if (!operationId || !interactionId || !pending) {
            res.status(404).json({ error: "Extension interaction not found" });
            return;
          }
          if (pending.interaction.id !== interactionId) {
            res.status(404).json({ error: "Extension interaction not found" });
            return;
          }
          const body = safeBody2(req);
          let value;
          if (body["cancelled"] === true) {
            clearTimeout(pending.timeout);
            pendingExtensionInteractions.delete(operationId);
            ctrl.updateOperation(operationId, {
              status: "failed",
              phase: void 0,
              interaction: void 0,
              error: "Extension operation cancelled"
            });
            pending.reject(new Error("Extension operation cancelled"));
            res.status(200).json({ accepted: true });
            return;
          }
          if (pending.interaction.kind === "marketplace_plugin") {
            const pluginName = body["pluginName"];
            if (typeof pluginName !== "string" || !pending.interaction.plugins.some(
              (plugin) => plugin.name === pluginName
            )) {
              res.status(400).json({ error: "Invalid marketplace plugin name" });
              return;
            }
            value = pluginName;
          } else {
            const settingValue = body["value"];
            if (typeof settingValue !== "string") {
              res.status(400).json({ error: "Extension setting value must be a string" });
              return;
            }
            value = settingValue;
          }
          clearTimeout(pending.timeout);
          pendingExtensionInteractions.delete(operationId);
          ctrl.updateOperation(operationId, {
            status: "running",
            phase: "preparing",
            interaction: void 0,
            error: void 0
          });
          pending.resolve(value);
          res.status(200).json({ accepted: true });
        } catch (err) {
          sendBridgeError2(res, err, {
            route: `POST ${base}/operations/:operationId/interactions/:interactionId`
          });
        }
      }
    );
    app.post(`${base}/install`, mutate({ strict: true }), async (req, res) => {
      const ctrl = resolve5(req, res, true);
      if (!ctrl) return;
      try {
        if (!ctrl.validateExtensionMutationClient(req, res, {
          requireClientId: false
        })) {
          return;
        }
        const body = safeBody2(req);
        const source = body["source"];
        const ref = body["ref"];
        const autoUpdate = body["autoUpdate"];
        const allowPreRelease = body["allowPreRelease"];
        const registry = body["registry"];
        const consent = body["consent"];
        if (!source || typeof source !== "string") {
          res.status(400).json({ error: "Missing or invalid source" });
          return;
        }
        if (ref !== void 0 && (typeof ref !== "string" || ref === "")) {
          res.status(400).json({ error: "`ref` must be a string" });
          return;
        }
        if (typeof ref === "string" && ref.startsWith("-")) {
          res.status(400).json({ error: '`ref` must not start with "-"' });
          return;
        }
        if (autoUpdate !== void 0 && typeof autoUpdate !== "boolean") {
          res.status(400).json({ error: "`autoUpdate` must be a boolean" });
          return;
        }
        if (allowPreRelease !== void 0 && typeof allowPreRelease !== "boolean") {
          res.status(400).json({ error: "`allowPreRelease` must be a boolean" });
          return;
        }
        if (registry !== void 0 && typeof registry !== "string") {
          res.status(400).json({ error: "`registry` must be a string" });
          return;
        }
        const sourceValue = source;
        const refValue = typeof ref === "string" ? ref : void 0;
        const autoUpdateValue = typeof autoUpdate === "boolean" ? autoUpdate : void 0;
        const allowPreReleaseValue = typeof allowPreRelease === "boolean" ? allowPreRelease : void 0;
        const registryValue = typeof registry === "string" ? registry : void 0;
        const registryUrl = registryValue !== void 0 ? parseExtensionRegistryUrl(registryValue, res) : void 0;
        if (registryUrl === null) return;
        if (consent !== true) {
          res.status(400).json({
            error: "Extension installation requires explicit consent"
          });
          return;
        }
        if (!validateExtensionSourceHost(sourceValue, res)) {
          return;
        }
        const localSource = /^[A-Za-z]:[\\/]/.test(sourceValue) || sourceValue.startsWith("/") || sourceValue.startsWith(".");
        if (localSource) {
          try {
            const metadata = await parseInstallSource(sourceValue, {
              networkPolicy: "public"
            });
            if (metadata.type !== "git" && metadata.type !== "github-release" && metadata.type !== "npm") {
              res.status(400).json({
                error: "Only GitHub, Git, and npm extension installs are supported over the daemon endpoint."
              });
              return;
            }
          } catch (error2) {
            const message = error2 instanceof Error ? error2.message : "Invalid install source";
            res.status(400).json({
              error: redactUrlCredentials(
                message.replaceAll(
                  sourceValue,
                  redactExtensionDisplaySource(sourceValue)
                )
              )
            });
            return;
          }
        }
        const npmSource = sourceValue.startsWith("@");
        const remoteSource = npmSource || sourceValue.startsWith("https://") || /^[^/\s]+\/[^/\s]+/.test(sourceValue);
        if (!localSource && !remoteSource) {
          res.status(400).json({
            error: `Install source not found: ${redactExtensionDisplaySource(
              sourceValue
            )}`
          });
          return;
        }
        if (npmSource && refValue) {
          res.status(400).json({ error: "--ref is not applicable for npm extensions." });
          return;
        }
        if (!npmSource && registryValue) {
          res.status(400).json({
            error: "--registry is only applicable for npm extensions."
          });
          return;
        }
        ctrl.runQueuedExtensionMutation(
          "install",
          { source: sourceValue },
          res,
          async (extensionManager, _signal, context, operationId) => {
            const prepared = await context.prepare(async (signal) => {
              const installMetadata = await parseInstallSource(sourceValue, {
                networkPolicy: "public"
              });
              if (installMetadata.type !== "git" && installMetadata.type !== "github-release" && installMetadata.type !== "npm") {
                throw new Error(
                  "Only GitHub, Git, and npm extension installs are supported over the daemon endpoint."
                );
              }
              if (installMetadata.type === "npm" && refValue) {
                throw new Error("--ref is not applicable for npm extensions.");
              }
              if (installMetadata.type !== "npm" && registryValue) {
                throw new Error(
                  "--registry is only applicable for npm extensions."
                );
              }
              if (!validateExtensionSourceMetadata(installMetadata)) {
                throw new Error("`source` host is not allowed");
              }
              if (installMetadata.type === "npm" && registryUrl) {
                installMetadata.registryUrl = registryUrl;
              }
              supersedeActiveInstallOperations(ctrl, operationId);
              return await extensionManager.prepareExtensionInstall({
                installMetadata: {
                  ...installMetadata,
                  ref: refValue,
                  autoUpdate: autoUpdateValue,
                  allowPreRelease: allowPreReleaseValue
                },
                initialActivation: { scope: "user" },
                requestConsent: /* @__PURE__ */ __name(() => Promise.resolve(), "requestConsent"),
                signal
              });
            });
            try {
              const committed = await context.commit(
                async (onCommitted) => await extensionManager.commitPreparedExtension(
                  prepared,
                  onCommitted
                )
              );
              return {
                status: "installed",
                source: sourceValue,
                name: committed.identity.name,
                version: committed.version
              };
            } finally {
              await extensionManager.disposePreparedExtension(prepared);
            }
          },
          {
            createManager: /* @__PURE__ */ __name((operationId) => ctrl.createExtensionManager(
              void 0,
              void 0,
              extensionInteractionHandlers(ctrl, operationId)
            ), "createManager"),
            onSettled: /* @__PURE__ */ __name((operationId) => {
              supersededInstallOperations.delete(operationId);
              cancelPendingExtensionInteraction(
                operationId,
                "Extension operation ended"
              );
            }, "onSettled"),
            deadlineMs: EXTENSION_INTERACTIVE_PREPARE_DEADLINE_MS,
            ...globalReconciliationOptions()
          }
        );
      } catch (err) {
        sendBridgeError2(res, err, { route: `POST ${base}/install` });
      }
    });
    app.post(
      `${base}/check-updates`,
      mutate({ strict: true }),
      async (req, res) => {
        const ctrl = resolve5(req, res, true);
        if (!ctrl) return;
        let timer;
        let releaseOperationSlot;
        try {
          if (!ctrl.validateExtensionMutationClient(req, res, {
            requireClientId: false
          })) {
            return;
          }
          releaseOperationSlot = ctrl.acquireOperationSlot(res);
          if (!releaseOperationSlot) return;
          const extensionManager = ctrl.createExtensionManager();
          const updateStates = /* @__PURE__ */ Object.create(null);
          const deadline = new AbortController();
          timer = setTimeout(() => {
            const error2 = new Error(
              "Extension update check exceeded its preparation deadline."
            );
            error2.code = "extension_prepare_timeout";
            deadline.abort(error2);
          }, EXTENSION_UPDATE_CHECK_DEADLINE_MS);
          timer.unref();
          let rejectRefreshOnAbort;
          try {
            await Promise.race([
              extensionManager.refreshCache(),
              new Promise((_resolve, reject) => {
                rejectRefreshOnAbort = /* @__PURE__ */ __name(() => reject(deadline.signal.reason), "rejectRefreshOnAbort");
                deadline.signal.addEventListener(
                  "abort",
                  rejectRefreshOnAbort,
                  { once: true }
                );
              })
            ]);
          } finally {
            if (rejectRefreshOnAbort) {
              deadline.signal.removeEventListener(
                "abort",
                rejectRefreshOnAbort
              );
            }
          }
          await extensionManager.checkForAllExtensionUpdates(
            (name, state) => {
              updateStates[name] = state;
            },
            deadline.signal,
            async (task) => await ctrl.preparationQueue.run(task, {
              signal: deadline.signal
            })
          );
          const states = updateStates;
          res.status(200).json({ states });
        } catch (err) {
          sendBridgeError2(res, err, { route: `POST ${base}/check-updates` });
        } finally {
          if (timer) clearTimeout(timer);
          releaseOperationSlot?.();
        }
      }
    );
    app.post(`${base}/refresh`, mutate({ strict: true }), async (req, res) => {
      const ctrl = resolve5(req, res, true);
      if (!ctrl) return;
      try {
        if (!ctrl.validateExtensionMutationClient(req, res, {
          requireClientId: false
        })) {
          return;
        }
        const releaseOperationSlot = ctrl.acquireOperationSlot(res);
        if (!releaseOperationSlot) return;
        try {
          const result = await ctrl.refreshExtensionsForAllSessions();
          res.status(200).json(result);
        } finally {
          releaseOperationSlot();
        }
      } catch (err) {
        sendBridgeError2(res, err, { route: `POST ${base}/refresh` });
      }
    });
    app.post(
      `${base}/:name/enable`,
      mutate({ strict: true }),
      async (req, res) => {
        const ctrl = resolve5(req, res, true);
        if (!ctrl) return;
        try {
          if (!ctrl.validateExtensionMutationClient(req, res, {
            requireClientId: false
          })) {
            return;
          }
          const name = req.params["name"];
          if (!name) {
            res.status(400).json({ error: "Missing extension name" });
            return;
          }
          const scope = parseExtensionScope(safeBody2(req), res);
          if (scope === null) return;
          ctrl.runQueuedExtensionMutation(
            "enable",
            { name },
            res,
            async (extensionManager, _signal, context) => {
              const extension = findLoadedExtension(extensionManager, name);
              if (!extension) {
                throw new Error(`Extension "${name}" not found`);
              }
              await context.commit(
                async (onCommitted) => await extensionManager.enableExtension(
                  extension.name,
                  scope,
                  ctrl.boundWorkspace,
                  onCommitted
                )
              );
              return { status: "enabled", name: extension.name };
            },
            {
              ...scope === "User" /* User */ ? globalReconciliationOptions() : workspaceReconciliationOptions()
            }
          );
        } catch (err) {
          sendBridgeError2(res, err, { route: `POST ${base}/:name/enable` });
        }
      }
    );
    app.post(
      `${base}/:name/disable`,
      mutate({ strict: true }),
      async (req, res) => {
        const ctrl = resolve5(req, res, true);
        if (!ctrl) return;
        try {
          if (!ctrl.validateExtensionMutationClient(req, res, {
            requireClientId: false
          })) {
            return;
          }
          const name = req.params["name"];
          if (!name) {
            res.status(400).json({ error: "Missing extension name" });
            return;
          }
          const scope = parseExtensionScope(safeBody2(req), res);
          if (scope === null) return;
          ctrl.runQueuedExtensionMutation(
            "disable",
            { name },
            res,
            async (extensionManager, _signal, context) => {
              const extension = findLoadedExtension(extensionManager, name);
              if (!extension) {
                throw new Error(`Extension "${name}" not found`);
              }
              await context.commit(
                async (onCommitted) => await extensionManager.disableExtension(
                  extension.name,
                  scope,
                  ctrl.boundWorkspace,
                  onCommitted
                )
              );
              return { status: "disabled", name: extension.name };
            },
            {
              ...scope === "User" /* User */ ? globalReconciliationOptions() : workspaceReconciliationOptions()
            }
          );
        } catch (err) {
          sendBridgeError2(res, err, { route: `POST ${base}/:name/disable` });
        }
      }
    );
    app.post(
      `${base}/:name/update`,
      mutate({ strict: true }),
      async (req, res) => {
        const ctrl = resolve5(req, res, true);
        if (!ctrl) return;
        try {
          if (!ctrl.validateExtensionMutationClient(req, res, {
            requireClientId: false
          })) {
            return;
          }
          const name = req.params["name"];
          if (!name) {
            res.status(400).json({ error: "Missing extension name" });
            return;
          }
          ctrl.runQueuedExtensionMutation(
            "update",
            { name },
            res,
            async (extensionManager, _signal, context) => {
              const extension = findLoadedExtension(extensionManager, name);
              if (!extension) {
                throw new Error(`Extension "${name}" not found`);
              }
              let preparedResult;
              try {
                preparedResult = await context.prepare(
                  async (signal) => await extensionManager.prepareExtensionUpdate({
                    extension,
                    signal
                  })
                );
              } catch (error2) {
                const wrapped = new Error(
                  `Update check failed for extension "${extension.name}": ${error2 instanceof Error ? error2.message : String(error2)}`,
                  { cause: error2 }
                );
                if (error2 && typeof error2 === "object" && typeof error2.code === "string") {
                  wrapped.code = error2.code;
                }
                throw wrapped;
              }
              if (preparedResult.upToDate) {
                throw new Error(`Extension "${extension.name}" has no update`);
              }
              try {
                const committed = await context.commit(
                  async (onCommitted) => await extensionManager.commitPreparedExtension(
                    preparedResult.prepared,
                    onCommitted
                  )
                );
                return {
                  status: "updated",
                  name: extension.name,
                  version: committed.version
                };
              } finally {
                await extensionManager.disposePreparedExtension(
                  preparedResult.prepared
                );
              }
            },
            {
              createManager: /* @__PURE__ */ __name((operationId) => ctrl.createExtensionManager(
                void 0,
                void 0,
                extensionInteractionHandlers(ctrl, operationId)
              ), "createManager"),
              onSettled: /* @__PURE__ */ __name((operationId) => {
                cancelPendingExtensionInteraction(
                  operationId,
                  "Extension operation ended"
                );
              }, "onSettled"),
              deadlineMs: EXTENSION_INTERACTIVE_PREPARE_DEADLINE_MS,
              ...globalReconciliationOptions()
            }
          );
        } catch (err) {
          sendBridgeError2(res, err, { route: `POST ${base}/:name/update` });
        }
      }
    );
    app.delete(`${base}/:name`, mutate({ strict: true }), async (req, res) => {
      const ctrl = resolve5(req, res, true);
      if (!ctrl) return;
      try {
        if (!ctrl.validateExtensionMutationClient(req, res, {
          requireClientId: false
        })) {
          return;
        }
        const name = req.params["name"];
        if (!name) {
          res.status(400).json({ error: "Missing extension name" });
          return;
        }
        ctrl.runQueuedExtensionMutation(
          "uninstall",
          { name },
          res,
          async (extensionManager, _signal, context) => {
            const extension = findLoadedExtension(extensionManager, name);
            if (!extension) {
              throw new Error(`Extension "${name}" not found`);
            }
            await context.commit(
              async (onCommitted) => await extensionManager.uninstallExtension(
                extension.name,
                false,
                ctrl.boundWorkspace,
                onCommitted
              )
            );
            return { status: "uninstalled", name: extension.name };
          },
          {
            ...globalReconciliationOptions()
          }
        );
      } catch (err) {
        sendBridgeError2(res, err, { route: `DELETE ${base}/:name` });
      }
    });
  }, "registerFor");
  registerFor("/workspace/extensions", () => primaryController);
  const extensionById = /* @__PURE__ */ __name((manager, extensionId) => manager.getLoadedExtensions().find((extension) => extension.id === extensionId), "extensionById");
  const parseExtensionId = /* @__PURE__ */ __name((req, res) => {
    const extensionId = req.params["extensionId"];
    if (!extensionId || !/^[a-f0-9]{64}$/.test(extensionId)) {
      res.status(400).json({
        error: "Invalid extension id",
        code: "invalid_extension_id"
      });
      return null;
    }
    return extensionId;
  }, "parseExtensionId");
  const parseActivationState = /* @__PURE__ */ __name((req, res) => {
    const state = safeBody2(req)["state"];
    if (state !== "enabled" && state !== "disabled") {
      res.status(400).json({
        error: '`state` must be either "enabled" or "disabled"',
        code: "invalid_extension_activation"
      });
      return null;
    }
    return state;
  }, "parseActivationState");
  const sendOperation = /* @__PURE__ */ __name((req, res, route, manager, operation, failureContext, run, options = {}) => {
    if (!primaryController.validateExtensionMutationClient(req, res, {
      requireClientId: false,
      bridges: mutationClientBridges(options.refreshRuntimes)
    })) {
      return;
    }
    primaryController.runQueuedExtensionMutation(
      operation,
      failureContext,
      res,
      run,
      {
        manager,
        operationBasePath: "/extensions/operations",
        onRuntimeReconciled,
        reserveRuntimeReconciliation,
        ...options
      }
    );
  }, "sendOperation");
  app.get("/extensions", async (_req, res) => {
    try {
      const manager = primaryController.createExtensionManager(
        boundWorkspace,
        true
      );
      const snapshot = await manager.refreshCacheWithSnapshot();
      res.status(200).json({
        v: 1,
        generation: snapshot.generation,
        extensions: manager.getLoadedExtensions().map((extension) => {
          const policy = snapshot.extensions[extension.id];
          return {
            id: extension.id,
            name: extension.name,
            version: extension.version,
            ...extension.installMetadata?.type ? { installType: extension.installMetadata.type } : {},
            defaultActivation: policy?.defaultActivation ?? "enabled",
            workspaceOverrideCount: Object.values(
              policy?.workspaceOverrides ?? {}
            ).filter((activation) => activation !== "inherit").length
          };
        })
      });
    } catch (error2) {
      sendBridgeError2(res, error2, { route: "GET /extensions" });
    }
  });
  app.get("/extensions/operations/:operationId", (req, res) => {
    const operationId = req.params["operationId"];
    if (!operationId) {
      res.status(400).json({ error: "Missing extension operation id" });
      return;
    }
    const operation = primaryController.getOperation(operationId);
    if (!operation) {
      res.status(404).json({
        error: `Extension operation "${operationId}" not found`,
        code: "extension_operation_not_found"
      });
      return;
    }
    res.status(200).json(operation);
  });
  app.put(
    "/extensions/:extensionId/activation",
    mutate({ strict: true }),
    async (req, res) => {
      const extensionId = parseExtensionId(req, res);
      if (!extensionId) return;
      const state = parseActivationState(req, res);
      if (!state) return;
      const manager = primaryController.createExtensionManager(
        boundWorkspace,
        true
      );
      sendOperation(
        req,
        res,
        "PUT /extensions/:extensionId/activation",
        manager,
        "activation",
        { name: extensionId },
        async (extensionManager, _signal, context) => {
          const extension = extensionById(extensionManager, extensionId);
          if (!extension)
            throw new Error(`Extension "${extensionId}" not found`);
          await context.commit(
            async (onCommitted) => await extensionManager.setExtensionDefaultActivation(
              extensionId,
              state,
              onCommitted
            )
          );
          return {
            status: state === "enabled" ? "enabled" : "disabled",
            name: extension.name
          };
        },
        {
          ...workspaceRegistry ? { refreshRuntimes: /* @__PURE__ */ __name(() => workspaceRegistry.list(), "refreshRuntimes") } : {}
        }
      );
    }
  );
  app.post("/extensions/install", mutate({ strict: true }), (req, res) => {
    const body = safeBody2(req);
    const source = body["source"];
    const activation = body["activation"];
    const ref = body["ref"];
    const autoUpdate = body["autoUpdate"];
    const allowPreRelease = body["allowPreRelease"];
    const registry = body["registry"];
    if (typeof source !== "string" || !source) {
      res.status(400).json({ error: "Missing or invalid source" });
      return;
    }
    if (ref !== void 0 && (typeof ref !== "string" || !ref)) {
      res.status(400).json({ error: "`ref` must be a non-empty string" });
      return;
    }
    if (typeof ref === "string" && ref.startsWith("-")) {
      res.status(400).json({ error: '`ref` must not start with "-"' });
      return;
    }
    if (autoUpdate !== void 0 && typeof autoUpdate !== "boolean") {
      res.status(400).json({ error: "`autoUpdate` must be a boolean" });
      return;
    }
    if (allowPreRelease !== void 0 && typeof allowPreRelease !== "boolean") {
      res.status(400).json({ error: "`allowPreRelease` must be a boolean" });
      return;
    }
    if (registry !== void 0 && typeof registry !== "string") {
      res.status(400).json({ error: "`registry` must be a string" });
      return;
    }
    const registryUrl = typeof registry === "string" ? parseExtensionRegistryUrl(registry, res) : void 0;
    if (registryUrl === null) return;
    if (body["consent"] !== true) {
      res.status(400).json({
        error: "Extension installation requires explicit consent"
      });
      return;
    }
    if (!validateExtensionSourceHost(source, res)) return;
    if (!activation || typeof activation !== "object") {
      res.status(400).json({ error: "Missing initial activation" });
      return;
    }
    const activationRecord = activation;
    let initialActivation;
    if (activationRecord["scope"] === "user") {
      initialActivation = { scope: "user" };
    } else if (activationRecord["scope"] === "workspace" && typeof activationRecord["workspaceId"] === "string" && workspaceRegistry) {
      const runtime = workspaceRegistry.getByWorkspaceId(
        activationRecord["workspaceId"]
      );
      if (!runtime) {
        res.status(400).json({
          error: "Unknown activation workspace",
          code: "workspace_mismatch"
        });
        return;
      }
      if (!requireTrustedWorkspaceRuntime(runtime, res)) return;
      initialActivation = {
        scope: "workspace",
        workspacePath: runtime.workspaceCwd
      };
    } else {
      res.status(400).json({ error: "Invalid initial activation" });
      return;
    }
    const manager = primaryController.createExtensionManager(
      boundWorkspace,
      true
    );
    sendOperation(
      req,
      res,
      "POST /extensions/install",
      manager,
      "install",
      { source },
      async (extensionManager, _signal, context) => {
        const prepared = await context.prepare(async (signal) => {
          const metadata = await parseInstallSource(source, {
            networkPolicy: "public"
          });
          if (metadata.type !== "git" && metadata.type !== "github-release" && metadata.type !== "npm") {
            throw new Error(
              "Only GitHub, Git, and npm extension installs are supported over the daemon endpoint."
            );
          }
          if (!validateExtensionSourceMetadata(metadata)) {
            throw new Error("`source` host is not allowed");
          }
          if (metadata.type === "npm" && ref !== void 0) {
            throw new Error("--ref is not applicable for npm extensions.");
          }
          if (metadata.type !== "npm" && registryUrl !== void 0) {
            throw new Error(
              "--registry is only applicable for npm extensions."
            );
          }
          if (metadata.type === "npm" && registryUrl) {
            metadata.registryUrl = registryUrl;
          }
          return await extensionManager.prepareExtensionInstall({
            installMetadata: {
              ...metadata,
              ...typeof ref === "string" ? { ref } : {},
              ...typeof autoUpdate === "boolean" ? { autoUpdate } : {},
              ...typeof allowPreRelease === "boolean" ? { allowPreRelease } : {}
            },
            requestConsent: /* @__PURE__ */ __name(() => Promise.resolve(), "requestConsent"),
            cwd: boundWorkspace,
            initialActivation,
            signal
          });
        });
        try {
          const committed = await context.commit(
            async (onCommitted) => await extensionManager.commitPreparedExtension(
              prepared,
              onCommitted
            )
          );
          return {
            status: "installed",
            source,
            name: committed.identity.name,
            version: committed.version
          };
        } finally {
          await extensionManager.disposePreparedExtension(prepared);
        }
      },
      {
        deadlineMs: EXTENSION_PREPARE_DEADLINE_MS,
        ...workspaceRegistry ? { refreshRuntimes: /* @__PURE__ */ __name(() => workspaceRegistry.list(), "refreshRuntimes") } : {}
      }
    );
  });
  app.post(
    "/extensions/check-updates",
    mutate({ strict: true }),
    (req, res) => {
      const manager = primaryController.createExtensionManager(
        boundWorkspace,
        true
      );
      sendOperation(
        req,
        res,
        "POST /extensions/check-updates",
        manager,
        "check-updates",
        {},
        async (extensionManager, signal, context) => {
          const states = /* @__PURE__ */ Object.create(null);
          await extensionManager.checkForAllExtensionUpdates(
            (name, state) => {
              states[name] = state;
            },
            signal,
            async (task) => await context.prepare(async () => await task())
          );
          return { status: "checked", states };
        },
        {
          skipRefresh: true,
          deadlineMs: EXTENSION_UPDATE_CHECK_DEADLINE_MS
        }
      );
    }
  );
  app.post(
    "/extensions/:extensionId/update",
    mutate({ strict: true }),
    (req, res) => {
      const extensionId = parseExtensionId(req, res);
      if (!extensionId) return;
      const manager = primaryController.createExtensionManager(
        boundWorkspace,
        true
      );
      sendOperation(
        req,
        res,
        "POST /extensions/:extensionId/update",
        manager,
        "update",
        { name: extensionId },
        async (extensionManager, _signal, context) => {
          const extension = extensionById(extensionManager, extensionId);
          if (!extension)
            throw new Error(`Extension "${extensionId}" not found`);
          if (extension.installMetadata?.type !== "git" && extension.installMetadata?.type !== "archive-url" && extension.installMetadata?.type !== "github-release" && extension.installMetadata?.type !== "npm") {
            throw new Error(
              `Extension "${extension.name}" is not remotely updatable.`
            );
          }
          const preparedResult = await context.prepare(
            async (signal) => await extensionManager.prepareExtensionUpdate({
              extension,
              signal
            })
          );
          if (preparedResult.upToDate) {
            return {
              status: "checked",
              name: extension.name,
              updated: false,
              reason: "up_to_date"
            };
          }
          try {
            const committed = await context.commit(
              async (onCommitted) => await extensionManager.commitPreparedExtension(
                preparedResult.prepared,
                onCommitted
              )
            );
            return {
              status: "updated",
              name: extension.name,
              updated: true,
              version: committed.version
            };
          } finally {
            await extensionManager.disposePreparedExtension(
              preparedResult.prepared
            );
          }
        },
        {
          deadlineMs: EXTENSION_PREPARE_DEADLINE_MS,
          ...workspaceRegistry ? { refreshRuntimes: /* @__PURE__ */ __name(() => workspaceRegistry.list(), "refreshRuntimes") } : {}
        }
      );
    }
  );
  app.delete(
    "/extensions/:extensionId",
    mutate({ strict: true }),
    async (req, res) => {
      const extensionId = parseExtensionId(req, res);
      if (!extensionId) return;
      const route = "DELETE /extensions/:extensionId";
      if (!primaryController.validateExtensionMutationClient(req, res, {
        requireClientId: false,
        bridges: mutationClientBridges()
      })) {
        return;
      }
      try {
        const manager = primaryController.createExtensionManager(
          boundWorkspace,
          true
        );
        const snapshot = await manager.getExtensionStoreSnapshot();
        const policy = snapshot.extensions[extensionId];
        if (!policy) {
          res.status(204).end();
          return;
        }
        sendOperation(
          req,
          res,
          route,
          manager,
          "uninstall",
          { name: policy.name },
          async (extensionManager, _signal, context) => {
            await context.commit(
              async (onCommitted) => await extensionManager.uninstallExtensionById(
                extensionId,
                false,
                void 0,
                onCommitted
              )
            );
            return { status: "uninstalled", name: policy.name };
          },
          {
            ...workspaceRegistry ? { refreshRuntimes: /* @__PURE__ */ __name(() => workspaceRegistry.list(), "refreshRuntimes") } : {}
          }
        );
      } catch (error2) {
        sendBridgeError2(res, error2, { route });
      }
    }
  );
  if (workspaceRegistry) {
    const registry = workspaceRegistry;
    app.get("/workspaces/:workspace/extensions", async (req, res) => {
      const runtime = resolveWorkspaceRuntimeFromParam(registry, req, res);
      if (!runtime) return;
      try {
        const manager = primaryController.createExtensionManager(
          runtime.workspaceCwd,
          runtime.trusted
        );
        const snapshot = await manager.refreshCacheWithSnapshot();
        const extensions = manager.getLoadedExtensions().map((extension) => {
          const activation = manager.getExtensionActivationFromSnapshot(
            extension.id,
            snapshot,
            runtime.workspaceCwd
          );
          return {
            extensionId: extension.id,
            name: extension.name,
            version: extension.version,
            defaultActivation: activation.default,
            workspaceActivation: activation.workspace === "inherit" ? null : activation.workspace,
            effectiveActivation: activation.effective,
            activationSource: activation.source
          };
        });
        res.status(200).json({
          v: 1,
          workspaceId: runtime.workspaceId,
          workspaceCwd: runtime.workspaceCwd,
          trusted: runtime.trusted,
          desiredGeneration: snapshot.generation,
          appliedGeneration: appliedGenerationByWorkspaceId.get(runtime.workspaceId) ?? 0,
          extensions
        });
      } catch (error2) {
        sendBridgeError2(res, error2, {
          route: "GET /workspaces/:workspace/extensions"
        });
      }
    });
    app.put(
      "/workspaces/:workspace/extensions/:extensionId/activation",
      mutate({ strict: true }),
      (req, res) => {
        const runtime = resolveWorkspaceRuntimeFromParam(registry, req, res);
        if (!runtime || !requireTrustedWorkspaceRuntime(runtime, res)) return;
        const extensionId = parseExtensionId(req, res);
        if (!extensionId) return;
        const state = parseActivationState(req, res);
        if (!state) return;
        const manager = primaryController.createExtensionManager(
          runtime.workspaceCwd,
          true
        );
        sendOperation(
          req,
          res,
          "PUT /workspaces/:workspace/extensions/:extensionId/activation",
          manager,
          "activation",
          { name: extensionId },
          async (extensionManager, _signal, context) => {
            const extension = extensionById(extensionManager, extensionId);
            if (!extension) {
              throw new Error(`Extension "${extensionId}" not found`);
            }
            await context.commit(
              async (onCommitted) => await extensionManager.setExtensionWorkspaceActivation(
                extensionId,
                runtime.workspaceCwd,
                state,
                onCommitted
              )
            );
            return {
              status: state === "enabled" ? "enabled" : "disabled",
              name: extension.name
            };
          },
          { refreshRuntimes: [runtime] }
        );
      }
    );
    app.delete(
      "/workspaces/:workspace/extensions/:extensionId/activation",
      mutate({ strict: true }),
      (req, res) => {
        const runtime = resolveWorkspaceRuntimeFromParam(registry, req, res);
        if (!runtime || !requireTrustedWorkspaceRuntime(runtime, res)) return;
        const extensionId = parseExtensionId(req, res);
        if (!extensionId) return;
        const manager = primaryController.createExtensionManager(
          runtime.workspaceCwd,
          true
        );
        sendOperation(
          req,
          res,
          "DELETE /workspaces/:workspace/extensions/:extensionId/activation",
          manager,
          "activation",
          { name: extensionId },
          async (extensionManager, _signal, context) => {
            const extension = extensionById(extensionManager, extensionId);
            if (!extension) {
              throw new Error(`Extension "${extensionId}" not found`);
            }
            const snapshot = await context.commit(
              async (onCommitted) => await extensionManager.clearExtensionWorkspaceActivation(
                extensionId,
                runtime.workspaceCwd,
                onCommitted
              )
            );
            const activation = extensionManager.getExtensionActivationFromSnapshot(
              extensionId,
              snapshot,
              runtime.workspaceCwd
            );
            return { status: activation.effective, name: extension.name };
          },
          { refreshRuntimes: [runtime] }
        );
      }
    );
    app.post(
      "/workspaces/:workspace/extensions/refresh",
      mutate({ strict: true }),
      (req, res) => {
        const runtime = resolveWorkspaceRuntimeFromParam(registry, req, res);
        if (!runtime || !requireTrustedWorkspaceRuntime(runtime, res)) return;
        const manager = primaryController.createExtensionManager(
          runtime.workspaceCwd,
          true
        );
        sendOperation(
          req,
          res,
          "POST /workspaces/:workspace/extensions/refresh",
          manager,
          "refresh",
          {},
          async () => ({ status: "refreshed" }),
          { refreshRuntimes: [runtime] }
        );
      }
    );
  }
}
__name(registerWorkspaceExtensionRoutes, "registerWorkspaceExtensionRoutes");

// packages/cli/src/serve/routes/workspace-file-write.ts
init_esbuild_shims();
function getFsFactory3(req, res) {
  const context = getWorkspaceRouteContext(req);
  if (context) return context.runtime.routeFileSystemFactory;
  const factory = req.app.locals.fsFactory;
  if (!factory) {
    applyReadHeaders(res);
    res.status(500).json({
      errorKind: "internal_error",
      error: "workspace filesystem factory is not configured",
      status: 500
    });
    return null;
  }
  return factory;
}
__name(getFsFactory3, "getFsFactory");
function routeName2(req, legacyRoute) {
  const context = getWorkspaceRouteContext(req);
  if (!context) return legacyRoute;
  return `${context.routePrefix}${legacyRoute.slice("POST ".length)}`;
}
__name(routeName2, "routeName");
function getBridge(req, deps) {
  return getWorkspaceRouteContext(req)?.runtime.bridge ?? deps.bridge;
}
__name(getBridge, "getBridge");
function sendParseError(res, _route, error2) {
  applyReadHeaders(res);
  res.status(400).json({
    errorKind: "parse_error",
    error: error2,
    status: 400
  });
  return null;
}
__name(sendParseError, "sendParseError");
function requireBodyString(body, key, res, route) {
  const value = body[key];
  if (typeof value !== "string" || value.length === 0) {
    return sendParseError(res, route, `\`${key}\` must be a non-empty string`);
  }
  return value;
}
__name(requireBodyString, "requireBodyString");
function optionalBoolean(body, key, res, route) {
  const value = body[key];
  if (value === void 0) return void 0;
  if (typeof value !== "boolean") {
    return sendParseError(res, route, `\`${key}\` must be a boolean`);
  }
  return value;
}
__name(optionalBoolean, "optionalBoolean");
function optionalString(body, key, res, route) {
  const value = body[key];
  if (value === void 0) return void 0;
  if (typeof value !== "string" || value.length === 0) {
    return sendParseError(res, route, `\`${key}\` must be a non-empty string`);
  }
  return value;
}
__name(optionalString, "optionalString");
function optionalLineEnding(body, res, route) {
  const value = body["lineEnding"];
  if (value === void 0) return void 0;
  if (value !== "crlf" && value !== "lf") {
    return sendParseError(res, route, '`lineEnding` must be "lf" or "crlf"');
  }
  return value;
}
__name(optionalLineEnding, "optionalLineEnding");
function requiredHash(body, res, route) {
  const value = body["expectedHash"];
  if (!isContentHash(value)) {
    return sendParseError(
      res,
      route,
      "`expectedHash` must match sha256:<64 lowercase hex chars>"
    );
  }
  return value;
}
__name(requiredHash, "requiredHash");
function optionalHash(body, res, route) {
  const value = body["expectedHash"];
  if (value === void 0) return void 0;
  if (!isContentHash(value)) {
    return sendParseError(
      res,
      route,
      "`expectedHash` must match sha256:<64 lowercase hex chars>"
    );
  }
  return value;
}
__name(optionalHash, "optionalHash");
function resolveOriginatorClientId2(clientId, deps, res, req) {
  if (clientId === void 0) return void 0;
  const bridge = req ? getBridge(req, deps) : deps.bridge;
  if (!bridge.knownClientIds().has(clientId)) {
    applyReadHeaders(res);
    res.status(400).json({
      error: `Client id "${clientId}" is not registered for this workspace`,
      code: "invalid_client_id",
      clientId
    });
    return null;
  }
  return clientId;
}
__name(resolveOriginatorClientId2, "resolveOriginatorClientId");
async function handlePostFileWrite(req, res, deps) {
  const ROUTE2 = routeName2(req, "POST /file/write");
  const factory = getFsFactory3(req, res);
  if (!factory) return;
  const body = deps.safeBody(req);
  const queryPath = requireBodyString(body, "path", res, ROUTE2);
  if (queryPath === null) return;
  const content = body["content"];
  if (typeof content !== "string") {
    sendParseError(res, ROUTE2, "`content` must be a string");
    return;
  }
  const rawMode = body["mode"];
  if (rawMode !== "create" && rawMode !== "replace") {
    sendParseError(res, ROUTE2, '`mode` must be "create" or "replace"');
    return;
  }
  const mode = rawMode;
  const expectedHash = mode === "replace" ? requiredHash(body, res, ROUTE2) : optionalHash(body, res, ROUTE2);
  if (expectedHash === null) return;
  const bom = optionalBoolean(body, "bom", res, ROUTE2);
  if (bom === null) return;
  const encoding = optionalString(body, "encoding", res, ROUTE2);
  if (encoding === null) return;
  const lineEnding = optionalLineEnding(body, res, ROUTE2);
  if (lineEnding === null) return;
  const clientId = deps.parseClientId(req, res);
  if (clientId === null) return;
  const originatorClientId = resolveOriginatorClientId2(
    clientId,
    deps,
    res,
    req
  );
  if (originatorClientId === null) return;
  const fs3 = factory.forRequest({
    originatorClientId,
    route: ROUTE2
  });
  try {
    const resolved = await fs3.resolve(queryPath, "write");
    const out = await fs3.writeTextAtomic(resolved, content, {
      mode,
      ...expectedHash ? { expectedHash } : {},
      ...bom !== void 0 ? { bom } : {},
      ...encoding !== void 0 ? { encoding } : {},
      ...lineEnding !== void 0 ? { lineEnding } : {}
    });
    applyReadHeaders(res);
    res.status(out.created ? 201 : 200).json({
      kind: "file_write",
      path: workspaceRelative(req, resolved),
      mode,
      created: out.created,
      sizeBytes: out.sizeBytes,
      hash: out.hash,
      encoding: out.meta.encoding ?? "utf-8",
      bom: out.meta.bom === true,
      lineEnding: out.meta.lineEnding,
      matchedIgnore: out.meta.matchedIgnore ?? null
    });
  } catch (err) {
    sendFsError(res, err, ROUTE2);
  }
}
__name(handlePostFileWrite, "handlePostFileWrite");
async function handlePostFileEdit(req, res, deps) {
  const ROUTE2 = routeName2(req, "POST /file/edit");
  const factory = getFsFactory3(req, res);
  if (!factory) return;
  const body = deps.safeBody(req);
  const queryPath = requireBodyString(body, "path", res, ROUTE2);
  if (queryPath === null) return;
  const oldText = body["oldText"];
  if (typeof oldText !== "string") {
    sendParseError(res, ROUTE2, "`oldText` must be a string");
    return;
  }
  const newText = body["newText"];
  if (typeof newText !== "string") {
    sendParseError(res, ROUTE2, "`newText` must be a string");
    return;
  }
  const expectedHash = requiredHash(body, res, ROUTE2);
  if (expectedHash === null) return;
  const clientId = deps.parseClientId(req, res);
  if (clientId === null) return;
  const originatorClientId = resolveOriginatorClientId2(
    clientId,
    deps,
    res,
    req
  );
  if (originatorClientId === null) return;
  const fs3 = factory.forRequest({
    originatorClientId,
    route: ROUTE2
  });
  try {
    const resolved = await fs3.resolve(queryPath, "edit");
    const out = await fs3.editAtomic(resolved, oldText, newText, {
      expectedHash
    });
    applyReadHeaders(res);
    res.status(200).json({
      kind: "file_edit",
      path: workspaceRelative(req, resolved),
      replacements: 1,
      sizeBytes: out.writtenBytes,
      hash: out.hash,
      encoding: out.meta?.encoding ?? "utf-8",
      bom: out.meta?.bom === true,
      lineEnding: out.meta?.lineEnding ?? "lf",
      matchedIgnore: out.meta?.matchedIgnore ?? null
    });
  } catch (err) {
    sendFsError(res, err, ROUTE2);
  }
}
__name(handlePostFileEdit, "handlePostFileEdit");
function registerWorkspaceFileWriteRoutes(app, deps) {
  app.post(
    "/file/write",
    deps.mutate({ strict: true }),
    (req, res) => handlePostFileWrite(req, res, deps)
  );
  app.post(
    "/file/edit",
    deps.mutate({ strict: true }),
    (req, res) => handlePostFileEdit(req, res, deps)
  );
}
__name(registerWorkspaceFileWriteRoutes, "registerWorkspaceFileWriteRoutes");
function registerWorkspaceQualifiedFileWriteRoutes(app, deps) {
  const resolve5 = /* @__PURE__ */ __name((req, res) => {
    const runtime = resolveWorkspaceRuntimeFromParam(
      deps.workspaceRegistry,
      req,
      res
    );
    if (!runtime) return false;
    if (!requireTrustedWorkspaceRuntime(runtime, res)) return false;
    setWorkspaceRouteContext(req, {
      runtime,
      routePrefix: "POST /workspaces/:workspace"
    });
    return true;
  }, "resolve");
  app.post(
    "/workspaces/:workspace/file/write",
    deps.mutate({ strict: true }),
    (req, res) => {
      if (!resolve5(req, res)) return;
      void handlePostFileWrite(req, res, deps);
    }
  );
  app.post(
    "/workspaces/:workspace/file/edit",
    deps.mutate({ strict: true }),
    (req, res) => {
      if (!resolve5(req, res)) return;
      void handlePostFileEdit(req, res, deps);
    }
  );
}
__name(registerWorkspaceQualifiedFileWriteRoutes, "registerWorkspaceQualifiedFileWriteRoutes");

// packages/cli/src/serve/routes/workspace-trust.ts
init_esbuild_shims();
function sendTrustError(res, route, err) {
  writeStderrLine(
    `qwen serve: ${route} error: ${err instanceof Error ? err.message : String(err)}`
  );
  if (err instanceof FatalConfigError) {
    res.status(500).json({
      error: "Failed to load trusted folders",
      code: "trusted_folders_invalid"
    });
    return;
  }
  res.status(500).json({
    error: "Failed to process workspace trust request",
    code: "internal_error"
  });
}
__name(sendTrustError, "sendTrustError");
function registerWorkspaceTrustRoutes(app, deps) {
  const {
    boundWorkspace,
    workspace,
    mutate,
    safeBody: safeBody2,
    parseAndValidateClientId
  } = deps;
  app.get("/workspace/trust", async (_req, res) => {
    try {
      const status = await workspace.getWorkspaceTrustStatus({
        route: "GET /workspace/trust",
        workspaceCwd: boundWorkspace
      });
      res.status(200).json(status);
    } catch (err) {
      sendTrustError(res, "GET /workspace/trust", err);
    }
  });
  app.post(
    "/workspace/trust/request",
    mutate({ strict: true }),
    async (req, res) => {
      const body = safeBody2(req);
      const desiredState = body["desiredState"];
      if (desiredState !== "trusted" && desiredState !== "untrusted") {
        res.status(400).json({
          error: 'desiredState must be "trusted" or "untrusted"',
          code: "invalid_desired_state"
        });
        return;
      }
      const reason = body["reason"];
      if (reason !== void 0 && (typeof reason !== "string" || reason.length > MAX_TRUST_REASON_LENGTH)) {
        res.status(400).json({
          error: `reason must be a string up to ${MAX_TRUST_REASON_LENGTH} characters`,
          code: "invalid_reason"
        });
        return;
      }
      const clientId = parseAndValidateClientId(req, res);
      if (clientId === null) return;
      const ctx = {
        route: "POST /workspace/trust/request",
        workspaceCwd: boundWorkspace,
        ...clientId !== void 0 ? { originatorClientId: clientId } : {}
      };
      try {
        const status = await workspace.getWorkspaceTrustStatus(ctx);
        if (!status.folderTrustEnabled) {
          res.status(409).json({
            error: "Folder trust is disabled for this workspace",
            code: "folder_trust_disabled"
          });
          return;
        }
        const result = await workspace.requestWorkspaceTrustChange(ctx, {
          desiredState,
          ...reason !== void 0 ? { reason } : {}
        });
        res.status(202).json(result);
      } catch (err) {
        sendTrustError(res, "POST /workspace/trust/request", err);
      }
    }
  );
}
__name(registerWorkspaceTrustRoutes, "registerWorkspaceTrustRoutes");
function registerWorkspaceQualifiedTrustRoutes(app, deps) {
  const { workspaceRegistry, mutate, safeBody: safeBody2 } = deps;
  app.get("/workspaces/:workspace/trust", async (req, res) => {
    const runtime = resolveWorkspaceRuntimeFromParam(
      workspaceRegistry,
      req,
      res
    );
    if (!runtime) return;
    const route = "GET /workspaces/:workspace/trust";
    try {
      const status = await runtime.workspaceService.getWorkspaceTrustStatus({
        route,
        workspaceCwd: runtime.workspaceCwd
      });
      res.status(200).json(status);
    } catch (err) {
      sendTrustError(res, route, err);
    }
  });
  app.post(
    "/workspaces/:workspace/trust/request",
    mutate({ strict: true }),
    async (req, res) => {
      const runtime = resolveWorkspaceRuntimeFromParam(
        workspaceRegistry,
        req,
        res
      );
      if (!runtime) return;
      const body = safeBody2(req);
      const desiredState = body["desiredState"];
      if (desiredState !== "trusted" && desiredState !== "untrusted") {
        res.status(400).json({
          error: 'desiredState must be "trusted" or "untrusted"',
          code: "invalid_desired_state"
        });
        return;
      }
      const reason = body["reason"];
      if (reason !== void 0 && (typeof reason !== "string" || reason.length > MAX_TRUST_REASON_LENGTH)) {
        res.status(400).json({
          error: `reason must be a string up to ${MAX_TRUST_REASON_LENGTH} characters`,
          code: "invalid_reason"
        });
        return;
      }
      const clientId = parseAndValidateWorkspaceClientId(
        req,
        res,
        runtime.bridge
      );
      if (clientId === null) return;
      const route = "POST /workspaces/:workspace/trust/request";
      const ctx = {
        route,
        workspaceCwd: runtime.workspaceCwd,
        ...clientId !== void 0 ? { originatorClientId: clientId } : {}
      };
      try {
        const status = await runtime.workspaceService.getWorkspaceTrustStatus(ctx);
        if (!status.folderTrustEnabled) {
          res.status(409).json({
            error: "Folder trust is disabled for this workspace",
            code: "folder_trust_disabled"
          });
          return;
        }
        const result = await runtime.workspaceService.requestWorkspaceTrustChange(ctx, {
          desiredState,
          ...reason !== void 0 ? { reason } : {}
        });
        res.status(202).json(result);
      } catch (err) {
        sendTrustError(res, route, err);
      }
    }
  );
}
__name(registerWorkspaceQualifiedTrustRoutes, "registerWorkspaceQualifiedTrustRoutes");

// packages/cli/src/serve/routes/permission.ts
init_esbuild_shims();

// packages/cli/src/serve/routes/session-runtime.ts
init_esbuild_shims();
function requireSessionRuntime(opts) {
  const {
    sessionId,
    route,
    res,
    workspaceRegistry,
    daemonLog,
    details = {}
  } = opts;
  if (workspaceRegistry.list().length === 1) {
    return workspaceRegistry.primary;
  }
  const resolution = workspaceRegistry.resolveLiveSessionOwner(sessionId);
  if (resolution.kind === "found") {
    const runtime = resolution.runtime;
    if (!runtime.primary && !runtime.trusted) {
      daemonLog?.warn("session routing failed", {
        route,
        resolutionKind: "untrusted_workspace",
        sessionId,
        workspaceId: runtime.workspaceId,
        workspaceCwd: runtime.workspaceCwd,
        ...details
      });
      sendUntrustedWorkspaceResponse(res, {
        sessionId,
        workspaceCwd: runtime.workspaceCwd,
        workspaceId: runtime.workspaceId
      });
      return void 0;
    }
    return runtime;
  }
  if (resolution.kind === "not_found") {
    daemonLog?.warn("session routing failed", {
      route,
      resolutionKind: "not_found",
      sessionId,
      ...details
    });
    res.status(404).json({
      error: `No session with id "${sessionId}"`,
      code: "session_not_found",
      sessionId
    });
    return void 0;
  }
  const workspaceIds = resolution.runtimes.map(
    (runtime) => runtime.workspaceId
  );
  daemonLog?.warn("session routing failed", {
    route,
    resolutionKind: "ambiguous",
    sessionId,
    workspaceIds,
    ...details
  });
  res.status(500).json({
    error: `Session owner is ambiguous for "${sessionId}"`,
    code: "ambiguous_session_owner",
    sessionId,
    route,
    workspaceIds
  });
  return void 0;
}
__name(requireSessionRuntime, "requireSessionRuntime");

// packages/cli/src/serve/routes/permission.ts
function registerPermissionRoutes(app, deps) {
  const {
    bridge,
    workspaceRegistry,
    daemonLog,
    mutate,
    sendPermissionVoteError: sendPermissionVoteError2
  } = deps;
  app.post("/session/:id/permission/:requestId", mutate(), (req, res) => {
    const sessionId = req.params["id"];
    const requestId = req.params["requestId"];
    const response = parsePermissionVoteBody(req, res);
    if (response === void 0) return;
    const clientId = parseClientIdHeader(req, res);
    if (clientId === null) return;
    const fromLoopback = detectFromLoopback(req);
    const context = {
      ...clientId !== void 0 ? { clientId } : {},
      fromLoopback
    };
    let accepted;
    try {
      const runtime = requireSessionRuntime({
        sessionId,
        route: "POST /session/:id/permission/:requestId",
        res,
        workspaceRegistry,
        daemonLog,
        details: { requestId }
      });
      if (!runtime) return;
      accepted = runtime.bridge.respondToSessionPermission(
        sessionId,
        requestId,
        response,
        context
      );
    } catch (err) {
      sendPermissionVoteError2(res, err, {
        route: "POST /session/:id/permission/:requestId",
        sessionId
      });
      return;
    }
    if (!accepted) {
      res.status(404).json({
        error: "No pending permission request for session",
        sessionId,
        requestId
      });
      return;
    }
    res.status(200).json({});
  });
  app.post("/permission/:requestId", mutate(), (req, res) => {
    const requestId = req.params["requestId"];
    const response = parsePermissionVoteBody(req, res);
    if (response === void 0) return;
    const clientId = parseClientIdHeader(req, res);
    if (clientId === null) return;
    const fromLoopback = detectFromLoopback(req);
    const context = {
      ...clientId !== void 0 ? { clientId } : {},
      fromLoopback
    };
    let accepted;
    try {
      accepted = bridge.respondToPermission(requestId, response, context);
    } catch (err) {
      sendPermissionVoteError2(res, err, {
        route: "POST /permission/:requestId"
      });
      return;
    }
    if (!accepted) {
      res.status(404).json({ error: "No pending permission request", requestId });
      return;
    }
    res.status(200).json({});
  });
}
__name(registerPermissionRoutes, "registerPermissionRoutes");

// packages/cli/src/serve/routes/session.ts
init_esbuild_shims();
import * as crypto3 from "node:crypto";
import * as path11 from "node:path";

// packages/cli/src/serve/server/prompt-deadline.ts
init_esbuild_shims();
var PromptDeadlineExceededError = class extends Error {
  static {
    __name(this, "PromptDeadlineExceededError");
  }
  deadlineMs;
  constructor(deadlineMs) {
    super(`prompt exceeded the ${deadlineMs}ms deadline`);
    this.name = "PromptDeadlineExceededError";
    this.deadlineMs = deadlineMs;
  }
};
function resolvePromptDeadlineMs(serverMs, requestMs) {
  if (serverMs === void 0 || !Number.isFinite(serverMs) || serverMs <= 0) {
    return void 0;
  }
  if (requestMs === void 0 || !Number.isFinite(requestMs) || requestMs <= 0) {
    return serverMs;
  }
  return Math.min(serverMs, requestMs);
}
__name(resolvePromptDeadlineMs, "resolvePromptDeadlineMs");

// packages/cli/src/serve/server/session-list.ts
init_esbuild_shims();
var DEFAULT_SESSION_PAGE_SIZE = 20;
var MAX_SESSION_PAGE_SIZE = 100;
var MAX_ORGANIZED_SESSIONS = 5e4;
var InvalidCursorError = class extends Error {
  static {
    __name(this, "InvalidCursorError");
  }
  constructor(cursor, kind = "numeric") {
    super(`Invalid cursor: "${cursor}" is not a valid ${kind} cursor`);
    this.name = "InvalidCursorError";
  }
};
function parseSessionCursor(cursor) {
  if (cursor === "") return void 0;
  const trimmed = cursor.trim();
  const parsed = Number(trimmed);
  if (trimmed === "" || !Number.isFinite(parsed) || parsed < 0 || parsed > Number.MAX_SAFE_INTEGER) {
    throw new InvalidCursorError(cursor);
  }
  return parsed;
}
__name(parseSessionCursor, "parseSessionCursor");
function parseOrganizedCursor(cursor, expected) {
  if (cursor === "") return void 0;
  try {
    const decoded = Buffer.from(cursor, "base64url").toString("utf8");
    const parsed = JSON.parse(decoded);
    const last = parsed.last;
    if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed) || typeof last !== "object" || last === null || Array.isArray(last) || typeof last.isPinned !== "boolean" || typeof last.activityTime !== "number" || !Number.isFinite(last.activityTime) || typeof last.sessionId !== "string" || last.sessionId.length === 0 || parsed.group !== expected.group || parsed.archiveState !== expected.archiveState || parsed.sourceType !== expected.sourceType || parsed.sourceId !== expected.sourceId) {
      throw new Error("invalid organized cursor");
    }
    return last;
  } catch {
    throw new InvalidCursorError(cursor, "organized");
  }
}
__name(parseOrganizedCursor, "parseOrganizedCursor");
function encodeOrganizedCursor(last, group, archiveState, sourceType, sourceId) {
  return Buffer.from(
    JSON.stringify({ group, archiveState, sourceType, sourceId, last }),
    "utf8"
  ).toString("base64url");
}
__name(encodeOrganizedCursor, "encodeOrganizedCursor");
function parseLiveSessionCursor(cursor) {
  if (cursor === "") return void 0;
  try {
    const parsed = JSON.parse(
      Buffer.from(cursor, "base64url").toString("utf8")
    );
    if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed) || typeof parsed.activityTime !== "number" || !Number.isFinite(parsed.activityTime) || typeof parsed.sessionId !== "string" || parsed.sessionId.length === 0) {
      throw new Error("invalid live cursor");
    }
    return parsed;
  } catch {
    throw new InvalidCursorError(cursor, "live");
  }
}
__name(parseLiveSessionCursor, "parseLiveSessionCursor");
function encodeLiveSessionCursor(last) {
  return Buffer.from(JSON.stringify(last), "utf8").toString("base64url");
}
__name(encodeLiveSessionCursor, "encodeLiveSessionCursor");
function matchesSessionMetadataSource(session, filter) {
  const sourceTypeMatches = filter.sourceType === void 0 || session.sourceType === filter.sourceType || // Legacy sessions without source metadata belong to the default catalog.
  filter.sourceType === "default" && session.sourceType === void 0;
  return sourceTypeMatches && // sourceId remains exact; only the default source type has legacy fallback.
  (filter.sourceId === void 0 || session.sourceId === filter.sourceId);
}
__name(matchesSessionMetadataSource, "matchesSessionMetadataSource");
function parseMetadataSessionCursor(cursor, expected) {
  if (cursor === "") return void 0;
  try {
    const parsed = JSON.parse(
      Buffer.from(cursor, "base64url").toString("utf8")
    );
    const last = parsed.last;
    if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed) || typeof last !== "object" || last === null || Array.isArray(last) || typeof last.activityTime !== "number" || !Number.isFinite(last.activityTime) || typeof last.sessionId !== "string" || last.sessionId.length === 0 || parsed.parentSessionId !== expected.parentSessionId || parsed.sourceType !== expected.sourceType || parsed.sourceId !== expected.sourceId || parsed.archiveState !== expected.archiveState) {
      throw new Error("invalid metadata cursor");
    }
    return { activityTime: last.activityTime, sessionId: last.sessionId };
  } catch {
    throw new InvalidCursorError(
      cursor,
      expected.sourceType === void 0 ? "parent" : "metadata"
    );
  }
}
__name(parseMetadataSessionCursor, "parseMetadataSessionCursor");
function encodeMetadataSessionCursor(last, filter, archiveState) {
  return Buffer.from(
    JSON.stringify({ ...filter, archiveState, last }),
    "utf8"
  ).toString("base64url");
}
__name(encodeMetadataSessionCursor, "encodeMetadataSessionCursor");
function toSummary2(item) {
  return {
    sessionId: item.sessionId,
    workspaceCwd: item.cwd,
    createdAt: item.startTime,
    updatedAt: new Date(item.mtime).toISOString(),
    displayName: item.customTitle || item.prompt,
    ...item.parentSessionId ? { parentSessionId: item.parentSessionId } : {},
    ...item.sourceType ? { sourceType: item.sourceType } : {},
    ...item.sourceId !== void 0 ? { sourceId: item.sourceId } : {},
    clientCount: 0,
    hasActivePrompt: false,
    isArchived: item.isArchived === true
  };
}
__name(toSummary2, "toSummary");
function mergeLiveSessionSummary(existing, live) {
  return {
    ...existing,
    ...live,
    createdAt: existing.createdAt,
    displayName: live.displayName ?? existing.displayName,
    // Immutable lineage; the persisted transcript is authoritative, and a live
    // entry only carries it when spawned this run.
    parentSessionId: existing.parentSessionId ?? live.parentSessionId,
    sourceType: existing.sourceType ?? live.sourceType,
    sourceId: existing.sourceType !== void 0 ? existing.sourceId : live.sourceId,
    updatedAt: live.updatedAt ?? existing.updatedAt,
    clientCount: live.clientCount,
    hasActivePrompt: live.hasActivePrompt,
    isArchived: false
  };
}
__name(mergeLiveSessionSummary, "mergeLiveSessionSummary");
async function listAllPersistedSummaries(sessionService, archiveState) {
  const sessions = [];
  let truncated = false;
  let cursor;
  do {
    const page = await sessionService.listSessions({
      cursor,
      size: 1e4,
      archiveState
    });
    const remaining = MAX_ORGANIZED_SESSIONS - sessions.length;
    sessions.push(...page.items.slice(0, remaining).map(toSummary2));
    cursor = page.nextCursor;
    if (page.items.length === 0) {
      break;
    }
    if (page.items.length > remaining || sessions.length >= MAX_ORGANIZED_SESSIONS && cursor !== void 0) {
      writeStderrLine(
        `qwen serve: organized session list truncated at ${MAX_ORGANIZED_SESSIONS} sessions`
      );
      truncated = true;
      break;
    }
  } while (cursor !== void 0);
  return { sessions, truncated };
}
__name(listAllPersistedSummaries, "listAllPersistedSummaries");
function getSummaryActivityTime(session) {
  const time = Date.parse(session.updatedAt ?? session.createdAt);
  return Number.isFinite(time) ? time : 0;
}
__name(getSummaryActivityTime, "getSummaryActivityTime");
function getLiveSessionCursorKey(session) {
  return {
    activityTime: getSummaryActivityTime(session),
    sessionId: session.sessionId
  };
}
__name(getLiveSessionCursorKey, "getLiveSessionCursorKey");
function compareLiveSessionCursorKeys(a, b) {
  const byTime = b.activityTime - a.activityTime;
  if (byTime !== 0) return byTime;
  return a.sessionId.localeCompare(b.sessionId);
}
__name(compareLiveSessionCursorKeys, "compareLiveSessionCursorKeys");
function compareOrganizedSessions(activityTimeById, a, b) {
  return compareOrganizedCursorKeys(
    getOrganizedCursorKey(activityTimeById, a),
    getOrganizedCursorKey(activityTimeById, b)
  );
}
__name(compareOrganizedSessions, "compareOrganizedSessions");
function getOrganizedCursorKey(activityTimeById, session) {
  return {
    isPinned: session.isPinned === true,
    activityTime: activityTimeById.get(session.sessionId) ?? 0,
    sessionId: session.sessionId
  };
}
__name(getOrganizedCursorKey, "getOrganizedCursorKey");
function compareOrganizedCursorKeys(a, b) {
  const byPinned = Number(b.isPinned) - Number(a.isPinned);
  if (byPinned !== 0) return byPinned;
  const byTime = b.activityTime - a.activityTime;
  if (byTime !== 0) return byTime;
  return a.sessionId.localeCompare(b.sessionId);
}
__name(compareOrganizedCursorKeys, "compareOrganizedCursorKeys");
function applyOrganization(session, organization) {
  return {
    ...session,
    groupId: organization?.groupId ?? null,
    color: organization?.color ?? null,
    isPinned: organization?.isPinned === true,
    ...organization?.pinnedAt !== void 0 ? { pinnedAt: organization.pinnedAt } : {}
  };
}
__name(applyOrganization, "applyOrganization");
async function listOrganizedWorkspaceSessionsForResponse(bridge, workspaceCwd, options, pageSize, readOptions) {
  const archiveState = options.archiveState ?? "active";
  const sessionService = new SessionService(workspaceCwd);
  const organizationService = createSessionOrganizationService(workspaceCwd);
  const snapshot = await organizationService.readSnapshot();
  const knownGroupIds = new Set(snapshot.groups.map((group2) => group2.id));
  const group = options.group ?? "all";
  if (group !== "all" && group !== "pinned" && group !== "ungrouped" && !knownGroupIds.has(group)) {
    throw new SessionOrganizationError(
      `Group not found: ${group}`,
      "group_not_found",
      "group"
    );
  }
  const cursorKey = options.cursor !== void 0 ? parseOrganizedCursor(options.cursor, {
    group,
    archiveState,
    sourceType: options.sourceType,
    sourceId: options.sourceId
  }) : void 0;
  const isFirstPage = cursorKey === void 0;
  let liveMergeFailed = false;
  const bySessionId = /* @__PURE__ */ new Map();
  const persisted = await listAllPersistedSummaries(
    sessionService,
    archiveState
  );
  for (const session of persisted.sessions) {
    bySessionId.set(
      session.sessionId,
      applyOrganization(session, snapshot.sessions.get(session.sessionId))
    );
  }
  if (readOptions.mergeLive !== false && archiveState !== "archived" && isFirstPage) {
    try {
      const liveSessions = bridge.listWorkspaceSessions(workspaceCwd);
      for (const live of liveSessions) {
        const existing = bySessionId.get(live.sessionId);
        const organization = snapshot.sessions.get(live.sessionId);
        if (existing) {
          bySessionId.set(
            live.sessionId,
            applyOrganization(
              mergeLiveSessionSummary(existing, live),
              organization
            )
          );
        } else if (!await sessionService.sessionExists(live.sessionId)) {
          bySessionId.set(
            live.sessionId,
            applyOrganization(
              {
                ...live,
                createdAt: live.createdAt,
                clientCount: live.clientCount,
                hasActivePrompt: live.hasActivePrompt,
                isArchived: false
              },
              organization
            )
          );
        }
      }
    } catch (error2) {
      liveMergeFailed = true;
      writeStderrLine(
        `qwen serve: organized session list live merge failed; using persisted sessions only: ${error2 instanceof Error ? error2.message : String(error2)}`
      );
    }
  }
  const filtered = [...bySessionId.values()].filter((session) => {
    if (!matchesSessionMetadataSource(session, options)) return false;
    if (group === "all") return true;
    if (group === "pinned") return session.isPinned === true;
    if (group === "ungrouped")
      return session.groupId == null && session.color == null;
    return session.color == null && session.groupId === group;
  });
  const activityTimeById = new Map(
    filtered.map((session) => [
      session.sessionId,
      getSummaryActivityTime(session)
    ])
  );
  filtered.sort((a, b) => compareOrganizedSessions(activityTimeById, a, b));
  const afterCursor = cursorKey === void 0 ? filtered : filtered.filter(
    (session) => compareOrganizedCursorKeys(
      cursorKey,
      getOrganizedCursorKey(activityTimeById, session)
    ) < 0
  );
  const page = afterCursor.slice(0, pageSize);
  const nextCursor = page.length < afterCursor.length ? encodeOrganizedCursor(
    getOrganizedCursorKey(activityTimeById, page[page.length - 1]),
    group,
    archiveState,
    options.sourceType,
    options.sourceId
  ) : void 0;
  return {
    sessions: page,
    ...nextCursor !== void 0 ? { nextCursor } : {},
    ...liveMergeFailed ? { liveMergeFailed: true } : {},
    ...persisted.truncated ? { truncated: true } : {}
  };
}
__name(listOrganizedWorkspaceSessionsForResponse, "listOrganizedWorkspaceSessionsForResponse");
async function listWorkspaceSessionsByMetadataForResponse(bridge, workspaceCwd, options, pageSize, filter, readOptions) {
  const archiveState = options.archiveState ?? "active";
  const sessionService = new SessionService(workspaceCwd);
  const bySessionId = /* @__PURE__ */ new Map();
  const persisted = await listAllPersistedSummaries(
    sessionService,
    archiveState
  );
  for (const session of persisted.sessions) {
    bySessionId.set(session.sessionId, session);
  }
  let liveMergeFailed = false;
  if (readOptions.mergeLive !== false && archiveState !== "archived") {
    try {
      for (const live of bridge.listWorkspaceSessions(workspaceCwd)) {
        const existing = bySessionId.get(live.sessionId);
        if (existing) {
          bySessionId.set(
            live.sessionId,
            mergeLiveSessionSummary(existing, live)
          );
        } else if (!await sessionService.sessionExists(live.sessionId)) {
          bySessionId.set(live.sessionId, {
            ...live,
            createdAt: live.createdAt,
            clientCount: live.clientCount,
            hasActivePrompt: live.hasActivePrompt,
            isArchived: false
          });
        }
      }
    } catch (error2) {
      liveMergeFailed = true;
      writeStderrLine(
        `qwen serve: session metadata filter live merge failed; using persisted sessions only: ${error2 instanceof Error ? error2.message : String(error2)}`
      );
    }
  }
  const matches = [...bySessionId.values()].filter(
    (session) => (filter.parentSessionId === void 0 || session.parentSessionId === filter.parentSessionId) && matchesSessionMetadataSource(session, filter)
  ).sort(
    (a, b) => compareLiveSessionCursorKeys(
      getLiveSessionCursorKey(a),
      getLiveSessionCursorKey(b)
    )
  );
  const cursorKey = options.cursor !== void 0 && options.cursor !== "" ? parseMetadataSessionCursor(options.cursor, {
    ...filter,
    archiveState
  }) : void 0;
  const afterCursor = cursorKey === void 0 ? matches : matches.filter(
    (session) => compareLiveSessionCursorKeys(
      cursorKey,
      getLiveSessionCursorKey(session)
    ) < 0
  );
  const page = afterCursor.slice(0, pageSize);
  const nextCursor = page.length < afterCursor.length ? encodeMetadataSessionCursor(
    getLiveSessionCursorKey(page[page.length - 1]),
    filter,
    archiveState
  ) : void 0;
  return {
    sessions: page,
    ...nextCursor !== void 0 ? { nextCursor } : {},
    ...liveMergeFailed ? { liveMergeFailed: true } : {},
    ...persisted.truncated ? { truncated: true } : {}
  };
}
__name(listWorkspaceSessionsByMetadataForResponse, "listWorkspaceSessionsByMetadataForResponse");
async function listWorkspaceSessionsForResponse(bridge, workspaceCwd, options, readOptions = {}) {
  const rawSize = options?.size;
  const requestedSize = typeof rawSize === "number" && Number.isSafeInteger(rawSize) ? rawSize : DEFAULT_SESSION_PAGE_SIZE;
  const pageSize = Math.min(Math.max(requestedSize, 1), MAX_SESSION_PAGE_SIZE);
  if (options?.view === "organized") {
    return listOrganizedWorkspaceSessionsForResponse(
      bridge,
      workspaceCwd,
      options,
      pageSize,
      readOptions
    );
  }
  if (options?.parentSessionId !== void 0 || options?.sourceType !== void 0) {
    return listWorkspaceSessionsByMetadataForResponse(
      bridge,
      workspaceCwd,
      options,
      pageSize,
      {
        ...options.parentSessionId !== void 0 ? { parentSessionId: options.parentSessionId } : {},
        ...options.sourceType !== void 0 ? { sourceType: options.sourceType } : {},
        ...options.sourceId !== void 0 ? { sourceId: options.sourceId } : {}
      },
      readOptions
    );
  }
  let numericCursor;
  if (options?.cursor != null) {
    numericCursor = parseSessionCursor(options.cursor);
  }
  const isFirstPage = numericCursor === void 0;
  const sessionService = new SessionService(workspaceCwd);
  const archiveState = options?.archiveState ?? "active";
  const persisted = await sessionService.listSessions({
    cursor: numericCursor,
    size: pageSize,
    archiveState
  });
  const bySessionId = /* @__PURE__ */ new Map();
  for (const item of persisted.items) {
    bySessionId.set(item.sessionId, toSummary2(item));
  }
  if (archiveState === "archived" || readOptions.mergeLive === false) {
    const sessions2 = [...bySessionId.values()];
    const nextCursor2 = persisted.nextCursor != null ? String(persisted.nextCursor) : void 0;
    return { sessions: sessions2, nextCursor: nextCursor2 };
  }
  const liveSessions = bridge.listWorkspaceSessions(workspaceCwd);
  for (const live of liveSessions) {
    const existing = bySessionId.get(live.sessionId);
    if (existing) {
      bySessionId.set(live.sessionId, mergeLiveSessionSummary(existing, live));
    } else if (isFirstPage && !await sessionService.sessionExists(live.sessionId)) {
      bySessionId.set(live.sessionId, {
        ...live,
        createdAt: live.createdAt,
        clientCount: live.clientCount,
        hasActivePrompt: live.hasActivePrompt,
        isArchived: false
      });
    }
  }
  const sessions = [...bySessionId.values()].sort((a, b) => {
    const aTime = Date.parse(a.updatedAt ?? a.createdAt);
    const bTime = Date.parse(b.updatedAt ?? b.createdAt);
    return bTime - aTime;
  });
  const nextCursor = persisted.nextCursor != null ? String(persisted.nextCursor) : void 0;
  return { sessions, nextCursor };
}
__name(listWorkspaceSessionsForResponse, "listWorkspaceSessionsForResponse");
function listLiveWorkspaceSessionsForResponse(bridge, workspaceCwd, options) {
  const rawSize = options?.size;
  const requestedSize = typeof rawSize === "number" && Number.isSafeInteger(rawSize) ? rawSize : DEFAULT_SESSION_PAGE_SIZE;
  const pageSize = Math.min(Math.max(requestedSize, 1), MAX_SESSION_PAGE_SIZE);
  const cursorKey = options?.cursor !== void 0 ? parseLiveSessionCursor(options.cursor) : void 0;
  const sessions = bridge.listWorkspaceSessions(workspaceCwd).sort(
    (a, b) => compareLiveSessionCursorKeys(
      getLiveSessionCursorKey(a),
      getLiveSessionCursorKey(b)
    )
  );
  const afterCursor = cursorKey === void 0 ? sessions : sessions.filter(
    (session) => compareLiveSessionCursorKeys(
      cursorKey,
      getLiveSessionCursorKey(session)
    ) < 0
  );
  const page = afterCursor.slice(0, pageSize);
  const nextCursor = page.length < afterCursor.length ? encodeLiveSessionCursor(getLiveSessionCursorKey(page[page.length - 1])) : void 0;
  return {
    sessions: page,
    ...nextCursor !== void 0 ? { nextCursor } : {}
  };
}
__name(listLiveWorkspaceSessionsForResponse, "listLiveWorkspaceSessionsForResponse");
function parseSessionPageSizeQuery(raw) {
  if (typeof raw !== "string") return void 0;
  const trimmed = raw.trim();
  if (!/^[+-]?\d+$/.test(trimmed)) return void 0;
  const parsed = Number.parseInt(trimmed, 10);
  if (!Number.isFinite(parsed)) return void 0;
  if (Number.isSafeInteger(parsed)) return parsed;
  return trimmed.startsWith("-") ? 1 : MAX_SESSION_PAGE_SIZE;
}
__name(parseSessionPageSizeQuery, "parseSessionPageSizeQuery");

// packages/cli/src/serve/server/session-export.ts
init_esbuild_shims();
var SESSION_EXPORT_FORMATS = ["html", "md", "json", "jsonl"];
var EXPORT_FORMATS = {
  html: {
    mimeType: "text/html; charset=utf-8",
    render: toHtml
  },
  md: {
    mimeType: "text/markdown; charset=utf-8",
    render: toMarkdown
  },
  json: {
    mimeType: "application/json; charset=utf-8",
    render: toJson
  },
  jsonl: {
    mimeType: "application/jsonl; charset=utf-8",
    render: toJsonl
  }
};
function parseSessionExportFormat(rawFormat) {
  if (rawFormat === void 0) return "html";
  if (typeof rawFormat !== "string") return void 0;
  return SESSION_EXPORT_FORMATS.includes(rawFormat) ? rawFormat : void 0;
}
__name(parseSessionExportFormat, "parseSessionExportFormat");
function sessionExportFormatValues() {
  return [...SESSION_EXPORT_FORMATS];
}
__name(sessionExportFormatValues, "sessionExportFormatValues");
async function exportSessionTranscript(params) {
  const { workspaceCwd, sessionId, format } = params;
  const service = new SessionService(workspaceCwd);
  const sessionData = params.archiveState === "archived" ? await service.loadArchivedSession(sessionId, {
    maxBytes: SESSION_TRANSCRIPT_MAX_INDEX_BYTES
  }) : await service.loadSession(sessionId);
  if (!sessionData) {
    throw new SessionNotFoundError(sessionId);
  }
  const exportConfig = params.config ?? {};
  const collected = await collectSessionData(
    sessionData.conversation,
    exportConfig
  );
  const normalized = normalizeSessionData(
    collected,
    sessionData.conversation.messages,
    exportConfig
  );
  const formatDefinition = EXPORT_FORMATS[format];
  return {
    format,
    filename: generateExportFilename(format),
    mimeType: formatDefinition.mimeType,
    content: formatDefinition.render(normalized)
  };
}
__name(exportSessionTranscript, "exportSessionTranscript");

// packages/cli/src/serve/routes/session.ts
var WORKSPACE_TRANSCRIPT_PAGE_SOURCE_MAX_BYTES = 4 * 1024 * 1024;
var WORKSPACE_TRANSCRIPT_RESPONSE_MAX_BYTES = 32 * 1024 * 1024;
var WORKSPACE_TRANSCRIPT_CURSOR_MAX_BYTES = 64 * 1024;
var TRANSCRIPT_CURSOR_TOO_LARGE_REPLAY_ERROR = "Transcript pagination state exceeds the safe limit";
var GENERATION_HEARTBEAT_MS = 15e3;
function formatGenerationSse(event, data) {
  return `event: ${event}
data: ${JSON.stringify({ v: 1, ...data })}

`;
}
__name(formatGenerationSse, "formatGenerationSse");
function writeGenerationSseChunk(res, chunk) {
  if (res.destroyed) {
    return Promise.reject(new Error("Generation SSE connection destroyed"));
  }
  const writable = res.write(chunk);
  const flush = res.flush;
  flush?.call(res);
  if (writable) {
    return res.destroyed ? Promise.reject(new Error("Generation SSE connection destroyed")) : Promise.resolve();
  }
  return new Promise((resolve5, reject) => {
    const cleanup = /* @__PURE__ */ __name(() => {
      res.off("drain", onDrain);
      res.off("close", onClose);
      res.off("error", onError);
    }, "cleanup");
    const onDrain = /* @__PURE__ */ __name(() => {
      cleanup();
      resolve5();
    }, "onDrain");
    const onClose = /* @__PURE__ */ __name(() => {
      cleanup();
      reject(new Error("Generation SSE connection closed"));
    }, "onClose");
    const onError = /* @__PURE__ */ __name((error2) => {
      cleanup();
      reject(error2);
    }, "onError");
    res.once("drain", onDrain);
    res.once("close", onClose);
    res.once("error", onError);
    if (res.destroyed) onClose();
  });
}
__name(writeGenerationSseChunk, "writeGenerationSseChunk");
function isReadOnlyWorkspaceInspection(runtime) {
  return !runtime.primary && !runtime.trusted;
}
__name(isReadOnlyWorkspaceInspection, "isReadOnlyWorkspaceInspection");
function runWorkspaceInspectionWithLogPolicy(runtime, read) {
  return isReadOnlyWorkspaceInspection(runtime) ? runWithoutDebugLogSession(read) : read();
}
__name(runWorkspaceInspectionWithLogPolicy, "runWorkspaceInspectionWithLogPolicy");
function requireSessionArtifactClientId(clientId, res) {
  if (clientId !== void 0) return true;
  res.status(403).json({
    error: "Session artifact access requires a session-bound client id",
    code: "client_id_required",
    errorKind: "client_id_required"
  });
  return false;
}
__name(requireSessionArtifactClientId, "requireSessionArtifactClientId");
function sendArtifactValidationError(res, err) {
  if (!(err instanceof SessionArtifactValidationError)) {
    return false;
  }
  res.status(400).json({
    v: 1,
    error: {
      code: err.code,
      message: err.message,
      ...err.field ? { field: err.field } : {}
    }
  });
  return true;
}
__name(sendArtifactValidationError, "sendArtifactValidationError");
function sendSessionOrganizationError(res, err) {
  if (!(err instanceof SessionOrganizationError)) {
    return false;
  }
  const status = err.code === "group_name_conflict" ? 409 : err.code === "group_not_found" ? 404 : err.code === "session_organization_store_unreadable" ? 500 : 400;
  res.status(status).json({
    error: err.message,
    code: err.code,
    ...err.field !== void 0 ? { field: err.field } : {}
  });
  return true;
}
__name(sendSessionOrganizationError, "sendSessionOrganizationError");
function parseTranscriptLimitQuery(rawLimit, res) {
  if (rawLimit === void 0) return void 0;
  if (typeof rawLimit !== "string" || rawLimit.trim() === "") {
    res.status(400).json({
      error: "`limit` must be a positive integer",
      code: "invalid_transcript_limit"
    });
    return null;
  }
  if (!/^\d+$/.test(rawLimit)) {
    res.status(400).json({
      error: "`limit` must be a positive integer",
      code: "invalid_transcript_limit"
    });
    return null;
  }
  const limit = Number(rawLimit);
  if (!Number.isSafeInteger(limit) || limit < 1 || limit > SESSION_TRANSCRIPT_MAX_LIMIT) {
    res.status(400).json({
      error: `\`limit\` must be between 1 and ${SESSION_TRANSCRIPT_MAX_LIMIT}`,
      code: "invalid_transcript_limit",
      maxLimit: SESSION_TRANSCRIPT_MAX_LIMIT
    });
    return null;
  }
  return limit;
}
__name(parseTranscriptLimitQuery, "parseTranscriptLimitQuery");
function parseTranscriptCursorQuery(rawCursor, res) {
  if (rawCursor === void 0) return void 0;
  if (typeof rawCursor !== "string" || rawCursor.trim() === "") {
    res.status(400).json({
      error: "`cursor` must be a non-empty string",
      code: "invalid_transcript_cursor"
    });
    return null;
  }
  return rawCursor;
}
__name(parseTranscriptCursorQuery, "parseTranscriptCursorQuery");
function workspaceTranscriptCursorExceedsLimit(cursor, maxBytes = WORKSPACE_TRANSCRIPT_CURSOR_MAX_BYTES) {
  return Buffer.byteLength(cursor) > maxBytes;
}
__name(workspaceTranscriptCursorExceedsLimit, "workspaceTranscriptCursorExceedsLimit");
function serializeWorkspaceTranscriptResponse(result, sessionId, maxBytes = WORKSPACE_TRANSCRIPT_RESPONSE_MAX_BYTES) {
  const serialized = JSON.stringify(result);
  const responseBytes = Buffer.byteLength(serialized);
  if (responseBytes > maxBytes) {
    throw new SessionTranscriptPageTooLargeError(
      sessionId,
      responseBytes,
      maxBytes
    );
  }
  return serialized;
}
__name(serializeWorkspaceTranscriptResponse, "serializeWorkspaceTranscriptResponse");
function transcriptSnapshotUnavailableError(sessionId) {
  return Object.assign(new Error("Transcript snapshot is unavailable"), {
    data: {
      errorKind: "transcript_snapshot_unavailable",
      sessionId
    }
  });
}
__name(transcriptSnapshotUnavailableError, "transcriptSnapshotUnavailableError");
function shouldPreserveTranscriptResolutionError(err) {
  return err instanceof SessionArchivedError || err instanceof SessionConflictError || err instanceof SessionNotFoundError;
}
__name(shouldPreserveTranscriptResolutionError, "shouldPreserveTranscriptResolutionError");
function parseOptionalApprovalMode(body, res) {
  const rawApprovalMode = body["approvalMode"];
  if (rawApprovalMode === void 0) {
    return void 0;
  }
  if (typeof rawApprovalMode !== "string" || !APPROVAL_MODES.includes(rawApprovalMode)) {
    res.status(400).json({
      error: "`approvalMode` must be a known approval mode when provided",
      code: "invalid_approval_mode",
      allowed: APPROVAL_MODES
    });
    return null;
  }
  return rawApprovalMode;
}
__name(parseOptionalApprovalMode, "parseOptionalApprovalMode");
function registerSessionRoutes(app, deps) {
  const {
    boundWorkspace,
    bridge,
    workspaceRegistry,
    archiveCoordinator,
    mutate,
    sendBridgeError: sendBridgeError2,
    daemonLog,
    promptDeadlineMs,
    sessionShellCommandEnabled
  } = deps;
  const LANGUAGE_CODES = deps.languageCodes;
  const transcriptCursorMasterKey = crypto3.randomBytes(32);
  const transcriptCursorCodecs = /* @__PURE__ */ new Map();
  const getTranscriptCursorCodec = /* @__PURE__ */ __name((runtime) => {
    const canonicalCwd = canonicalizeWorkspace(runtime.workspaceCwd);
    const cacheKey = `${runtime.workspaceId}\0${canonicalCwd}`;
    const cached = transcriptCursorCodecs.get(cacheKey);
    if (cached) return cached;
    const derivedKey = crypto3.hkdfSync(
      "sha256",
      transcriptCursorMasterKey,
      Buffer.alloc(0),
      Buffer.from(cacheKey, "utf8"),
      32
    );
    const codec = new SessionTranscriptCursorCodec(new Uint8Array(derivedKey));
    transcriptCursorCodecs.set(cacheKey, codec);
    return codec;
  }, "getTranscriptCursorCodec");
  const logSessionRoutingFailure = /* @__PURE__ */ __name((route, resolutionKind, details = {}) => {
    daemonLog?.warn("session routing failed", {
      route,
      resolutionKind,
      ...details
    });
  }, "logSessionRoutingFailure");
  const sendWorkspaceMismatch2 = /* @__PURE__ */ __name((res, requestedWorkspace) => {
    const runtimes = workspaceRegistry.list();
    if (runtimes.length > 1) {
      res.status(400).json({
        error: `Workspace mismatch: daemon is bound to ${runtimes.length} workspaces; none matched the requested workspace.`,
        code: "workspace_mismatch",
        boundWorkspace,
        workspaceCount: runtimes.length,
        requestedWorkspace
      });
      return;
    }
    res.status(400).json({
      error: `Workspace mismatch: daemon is bound to "${boundWorkspace}"`,
      code: "workspace_mismatch",
      boundWorkspace,
      requestedWorkspace
    });
  }, "sendWorkspaceMismatch");
  const resolveRuntimeForSessionCreation = /* @__PURE__ */ __name((body, res) => {
    const cwd = parseOptionalWorkspaceCwd(body, boundWorkspace, res);
    if (cwd === void 0) return void 0;
    let key;
    try {
      key = canonicalizeWorkspace(cwd);
    } catch (err) {
      if (workspaceRegistry.list().length > 1 && "cwd" in body) {
        logSessionRoutingFailure("POST /session", "workspace_mismatch", {
          requestedWorkspace: cwd
        });
        sendWorkspaceMismatch2(res, cwd);
        return void 0;
      }
      sendBridgeError2(res, err, { route: "POST /session" });
      return void 0;
    }
    if (workspaceRegistry.list().length === 1) {
      return {
        runtime: workspaceRegistry.primary,
        workspaceCwd: "cwd" in body ? key : workspaceRegistry.primary.workspaceCwd
      };
    }
    const runtime = workspaceRegistry.resolveWorkspaceCwd(
      "cwd" in body ? key : void 0
    );
    if (!runtime) {
      logSessionRoutingFailure("POST /session", "workspace_mismatch", {
        requestedWorkspace: key
      });
      sendWorkspaceMismatch2(res, key);
      return void 0;
    }
    if (!runtime.primary && !runtime.trusted) {
      logSessionRoutingFailure("POST /session", "untrusted_workspace", {
        workspaceId: runtime.workspaceId,
        workspaceCwd: runtime.workspaceCwd
      });
      sendUntrustedWorkspaceResponse(res, {
        workspaceCwd: runtime.workspaceCwd,
        workspaceId: runtime.workspaceId
      });
      return void 0;
    }
    return { runtime, workspaceCwd: runtime.workspaceCwd };
  }, "resolveRuntimeForSessionCreation");
  const resolveRuntimeFromWorkspaceParam = /* @__PURE__ */ __name((req, res, paramName = "id") => {
    const workspaceParam = req.params[paramName] ?? "";
    const byId = workspaceRegistry.getByWorkspaceId(workspaceParam);
    if (byId) return byId;
    if (!path11.isAbsolute(workspaceParam)) {
      res.status(400).json({
        error: `\`:${paramName}\` must decode to a workspace id or absolute path`
      });
      return null;
    }
    let key;
    try {
      key = canonicalizeWorkspace(workspaceParam);
    } catch {
      sendWorkspaceMismatch2(res, workspaceParam);
      return null;
    }
    const runtime = workspaceRegistry.getByWorkspaceCwd(key);
    if (!runtime) {
      sendWorkspaceMismatch2(res, key);
      return null;
    }
    return runtime;
  }, "resolveRuntimeFromWorkspaceParam");
  const resolveRuntimeForCatalogRoute = /* @__PURE__ */ __name((req, res, paramName, route) => {
    const runtime = paramName === "workspace" ? resolveWorkspaceRuntimeFromParam(
      workspaceRegistry,
      req,
      res,
      "workspace"
    ) : resolveRuntimeFromWorkspaceParam(req, res, paramName);
    if (runtime === null) return null;
    if (paramName === "workspace" && runtime.primary && !runtime.trusted) {
      logSessionRoutingFailure(route, "untrusted_workspace", {
        workspaceId: runtime.workspaceId,
        workspaceCwd: runtime.workspaceCwd
      });
      sendUntrustedWorkspaceResponse(res);
      return null;
    }
    return runtime;
  }, "resolveRuntimeForCatalogRoute");
  const hasActivePersistedSessions = /* @__PURE__ */ __name(async (workspaceCwd) => {
    try {
      const page = await new SessionService(workspaceCwd).listSessions({
        archiveState: "active",
        size: 1
      });
      return page.items.length > 0;
    } catch {
      return false;
    }
  }, "hasActivePersistedSessions");
  const isNumericSessionCursor = /* @__PURE__ */ __name((cursor) => {
    const trimmed = cursor.trim();
    if (trimmed === "") return false;
    const parsed = Number(trimmed);
    return Number.isFinite(parsed) && parsed >= 0 && parsed <= Number.MAX_SAFE_INTEGER;
  }, "isNumericSessionCursor");
  const requireTrustedRuntimeForWorkspaceRoute = /* @__PURE__ */ __name((req, res, route) => {
    const runtime = resolveWorkspaceRuntimeFromParam(
      workspaceRegistry,
      req,
      res,
      "workspace"
    );
    if (runtime === null) return null;
    if (!runtime.trusted) {
      logSessionRoutingFailure(route, "untrusted_workspace", {
        workspaceId: runtime.workspaceId,
        workspaceCwd: runtime.workspaceCwd
      });
      sendUntrustedWorkspaceResponse(res);
      return null;
    }
    return runtime;
  }, "requireTrustedRuntimeForWorkspaceRoute");
  const handleSessionExport = /* @__PURE__ */ __name(async (req, res, target) => {
    const sessionId = requireSessionId(req, res);
    if (sessionId === null) return;
    const rawFormat = req.query["format"];
    const format = parseSessionExportFormat(rawFormat);
    if (!format) {
      res.status(400).json({
        error: "Invalid export format",
        code: "invalid_export_format",
        format: typeof rawFormat === "string" ? rawFormat : String(rawFormat),
        allowedFormats: sessionExportFormatValues()
      });
      return;
    }
    try {
      const result = await archiveCoordinator.runSharedMany(
        [sessionId],
        async () => {
          if (target.archiveState === "archived") {
            await assertSessionArchived(target.workspaceCwd, sessionId);
          } else {
            await assertSessionLoadable(target.workspaceCwd, sessionId);
          }
          return exportSessionTranscript({
            workspaceCwd: target.workspaceCwd,
            sessionId,
            format,
            archiveState: target.archiveState,
            config: { getChannel: /* @__PURE__ */ __name(() => "daemon", "getChannel") }
          });
        }
      );
      const filename = result.filename.replace(/["\\\r\n]/g, "_");
      res.status(200).set("Cache-Control", "no-store").set("X-Content-Type-Options", "nosniff").set("Content-Type", result.mimeType).set("Content-Disposition", `attachment; filename="${filename}"`).send(result.content);
    } catch (err) {
      if (target.workspaceQualified && err instanceof SessionNotFoundError) {
        res.status(404).json({
          error: err.message,
          code: "session_not_found",
          sessionId: err.sessionId
        });
        return;
      }
      sendBridgeError2(res, err, {
        route: target.route,
        sessionId,
        ...target.workspaceQualified ? { workspaceCwd: target.workspaceCwd } : {}
      });
    }
  }, "handleSessionExport");
  const sendAmbiguousSessionOwner = /* @__PURE__ */ __name((res, route, sessionId, runtimes) => {
    const workspaceIds = runtimes.map((runtime) => runtime.workspaceId);
    logSessionRoutingFailure(route, "ambiguous", {
      sessionId,
      workspaceIds
    });
    res.status(500).json({
      error: `Session owner is ambiguous for "${sessionId}"`,
      code: "ambiguous_session_owner",
      sessionId,
      route,
      workspaceIds
    });
  }, "sendAmbiguousSessionOwner");
  const sendUntrustedSessionOwner = /* @__PURE__ */ __name((res, route, sessionId, runtime) => {
    logSessionRoutingFailure(route, "untrusted_workspace", {
      sessionId,
      workspaceId: runtime.workspaceId,
      workspaceCwd: runtime.workspaceCwd
    });
    sendUntrustedWorkspaceResponse(res, {
      sessionId,
      workspaceCwd: runtime.workspaceCwd,
      workspaceId: runtime.workspaceId
    });
  }, "sendUntrustedSessionOwner");
  const assertTrustedSessionOwner = /* @__PURE__ */ __name((res, route, sessionId, runtime) => {
    if (runtime.primary || runtime.trusted) {
      return true;
    }
    sendUntrustedSessionOwner(res, route, sessionId, runtime);
    return false;
  }, "assertTrustedSessionOwner");
  const inFlightRestoreOwners = /* @__PURE__ */ new Map();
  const sendSessionWorkspaceConflict = /* @__PURE__ */ __name((res, route, sessionId, runtime, liveRuntime) => {
    logSessionRoutingFailure(route, "workspace_conflict", {
      sessionId,
      workspaceId: runtime.workspaceId,
      workspaceCwd: runtime.workspaceCwd,
      liveWorkspaceId: liveRuntime.workspaceId,
      liveWorkspaceCwd: liveRuntime.workspaceCwd
    });
    res.status(409).json({
      error: `Session "${sessionId}" is already live or restoring in another workspace runtime.`,
      code: "session_workspace_conflict",
      sessionId,
      workspaceCwd: runtime.workspaceCwd,
      workspaceId: runtime.workspaceId,
      liveWorkspaceCwd: liveRuntime.workspaceCwd,
      liveWorkspaceId: liveRuntime.workspaceId
    });
  }, "sendSessionWorkspaceConflict");
  const enterRestoreOwner = /* @__PURE__ */ __name((res, route, sessionId, runtime) => {
    const existing = inFlightRestoreOwners.get(sessionId);
    if (existing && existing.workspaceCwd !== runtime.workspaceCwd) {
      const existingRuntime = workspaceRegistry.getByWorkspaceCwd(existing.workspaceCwd) ?? workspaceRegistry.primary;
      sendSessionWorkspaceConflict(
        res,
        route,
        sessionId,
        runtime,
        existingRuntime
      );
      return void 0;
    }
    if (existing) {
      existing.count += 1;
    } else {
      inFlightRestoreOwners.set(sessionId, {
        workspaceCwd: runtime.workspaceCwd,
        count: 1
      });
    }
    let released = false;
    return () => {
      if (released) return;
      released = true;
      const current = inFlightRestoreOwners.get(sessionId);
      if (!current || current.workspaceCwd !== runtime.workspaceCwd) return;
      current.count -= 1;
      if (current.count <= 0) {
        inFlightRestoreOwners.delete(sessionId);
      }
    };
  }, "enterRestoreOwner");
  const resolveRuntimeForSessionRestore = /* @__PURE__ */ __name((body, res, route, sessionId) => {
    const cwd = parseOptionalWorkspaceCwd(body, boundWorkspace, res);
    if (cwd === void 0) return void 0;
    let key;
    try {
      key = canonicalizeWorkspace(cwd);
    } catch (err) {
      if ("cwd" in body) {
        logSessionRoutingFailure(route, "workspace_mismatch", {
          requestedWorkspace: cwd
        });
        sendWorkspaceMismatch2(res, cwd);
        return void 0;
      }
      sendBridgeError2(res, err, { route, sessionId });
      return void 0;
    }
    const runtime = workspaceRegistry.resolveWorkspaceCwd(
      "cwd" in body ? key : void 0
    );
    if (!runtime) {
      logSessionRoutingFailure(route, "workspace_mismatch", {
        requestedWorkspace: key
      });
      sendWorkspaceMismatch2(res, key);
      return void 0;
    }
    if (!runtime.primary && !runtime.trusted) {
      logSessionRoutingFailure(route, "untrusted_workspace", {
        workspaceId: runtime.workspaceId,
        workspaceCwd: runtime.workspaceCwd
      });
      sendUntrustedWorkspaceResponse(res, {
        workspaceCwd: runtime.workspaceCwd,
        workspaceId: runtime.workspaceId
      });
      return void 0;
    }
    const liveOwner = workspaceRegistry.resolveLiveSessionOwner(sessionId);
    if (liveOwner.kind === "ambiguous") {
      sendAmbiguousSessionOwner(res, route, sessionId, liveOwner.runtimes);
      return void 0;
    }
    if (liveOwner.kind === "found" && liveOwner.runtime.workspaceCwd !== runtime.workspaceCwd) {
      sendSessionWorkspaceConflict(
        res,
        route,
        sessionId,
        runtime,
        liveOwner.runtime
      );
      return void 0;
    }
    return { runtime, workspaceCwd: runtime.workspaceCwd };
  }, "resolveRuntimeForSessionRestore");
  const resolveLiveSessionRuntime = /* @__PURE__ */ __name((sessionId, res, route) => requireSessionRuntime({
    sessionId,
    route,
    res,
    workspaceRegistry,
    daemonLog
  }), "resolveLiveSessionRuntime");
  const sendNonPrimarySessionRouteUnsupported = /* @__PURE__ */ __name((res, route, sessionId, runtime) => {
    res.status(400).json({
      error: `Route "${route}" is primary-only for non-primary workspace sessions in Phase 2a.`,
      code: "non_primary_session_route_not_supported",
      sessionId,
      workspaceId: runtime.workspaceId,
      workspaceCwd: runtime.workspaceCwd,
      route
    });
  }, "sendNonPrimarySessionRouteUnsupported");
  const withOwnerMutableSession = /* @__PURE__ */ __name((route, handler) => async (req, res) => {
    const sessionId = requireSessionId(req, res);
    if (sessionId === null) return;
    try {
      const runtime = resolveLiveSessionRuntime(sessionId, res, route);
      if (!runtime) return;
      await archiveCoordinator.runSharedMany([sessionId], async () => {
        await handler(req, res, sessionId, runtime);
      });
    } catch (err) {
      sendBridgeError2(res, err, { route, sessionId });
    }
  }, "withOwnerMutableSession");
  const withOwnerReadSession = /* @__PURE__ */ __name((route, handler) => async (req, res) => {
    const sessionId = requireSessionId(req, res);
    if (sessionId === null) return;
    try {
      const runtime = resolveLiveSessionRuntime(sessionId, res, route);
      if (!runtime) return;
      await handler(req, res, sessionId, runtime);
    } catch (err) {
      sendBridgeError2(res, err, { route, sessionId });
    }
  }, "withOwnerReadSession");
  const resolveTranscriptSessionRuntime = /* @__PURE__ */ __name(async (res, route, sessionId, hasCursor) => {
    const activeInRuntime = /* @__PURE__ */ __name(async (runtime) => {
      const location = await assertSessionLoadable(
        runtime.workspaceCwd,
        sessionId
      );
      return location === "active";
    }, "activeInRuntime");
    const throwMissingActiveTranscript = /* @__PURE__ */ __name(() => {
      if (hasCursor) {
        throw transcriptSnapshotUnavailableError(sessionId);
      }
      throw new SessionNotFoundError(sessionId);
    }, "throwMissingActiveTranscript");
    if (workspaceRegistry.list().length === 1) {
      const runtime = workspaceRegistry.primary;
      if (await activeInRuntime(runtime)) {
        return runtime;
      }
      return throwMissingActiveTranscript();
    }
    const liveOwner = workspaceRegistry.resolveLiveSessionOwner(sessionId);
    if (liveOwner.kind === "ambiguous") {
      sendAmbiguousSessionOwner(res, route, sessionId, liveOwner.runtimes);
      return void 0;
    }
    if (liveOwner.kind === "found") {
      if (!assertTrustedSessionOwner(res, route, sessionId, liveOwner.runtime)) {
        return void 0;
      }
      if (await activeInRuntime(liveOwner.runtime)) {
        return liveOwner.runtime;
      }
      return throwMissingActiveTranscript();
    }
    const activeRuntimes = [];
    let loadError;
    for (const runtime of workspaceRegistry.list()) {
      try {
        if (await activeInRuntime(runtime)) {
          activeRuntimes.push(runtime);
        }
      } catch (err) {
        if (loadError === void 0 || shouldPreserveTranscriptResolutionError(err)) {
          if (loadError !== void 0 && shouldPreserveTranscriptResolutionError(loadError)) {
            logSessionRoutingFailure(
              route,
              "transcript_resolution_error_superseded",
              {
                sessionId,
                supersededError: loadError instanceof Error ? loadError.name : String(loadError),
                newError: err instanceof Error ? err.name : String(err)
              }
            );
          }
          loadError = err;
        }
      }
    }
    if (activeRuntimes.length === 1) {
      const runtime = activeRuntimes[0];
      if (!assertTrustedSessionOwner(res, route, sessionId, runtime)) {
        return void 0;
      }
      return runtime;
    }
    if (activeRuntimes.length > 1) {
      sendAmbiguousSessionOwner(res, route, sessionId, activeRuntimes);
      return void 0;
    }
    if (loadError !== void 0) {
      if (shouldPreserveTranscriptResolutionError(loadError)) {
        throw loadError;
      }
      const runtimes = workspaceRegistry.list();
      const firstError = loadError instanceof Error ? loadError.message : String(loadError);
      daemonLog?.warn("transcript session resolution failed", {
        route,
        sessionId,
        workspaceCount: runtimes.length,
        error: firstError
      });
      throw new Error(
        `Transcript session resolution failed across ${runtimes.length} workspace(s)`
      );
    }
    return throwMissingActiveTranscript();
  }, "resolveTranscriptSessionRuntime");
  const parseSessionIdsBody = /* @__PURE__ */ __name((req, res) => {
    const body = safeBody(req);
    const sessionIds = body["sessionIds"];
    if (!Array.isArray(sessionIds) || sessionIds.length === 0 || sessionIds.length > 100 || !sessionIds.every((id) => typeof id === "string")) {
      res.status(400).json({
        error: "`sessionIds` must be a non-empty string array (max 100)",
        code: "invalid_request"
      });
      return void 0;
    }
    return [...new Set(sessionIds)];
  }, "parseSessionIdsBody");
  const serializeSessionErrors = /* @__PURE__ */ __name((errors) => errors.map((e) => ({
    sessionId: e.sessionId,
    error: e.error instanceof Error ? e.error.message : String(e.error)
  })), "serializeSessionErrors");
  const resolveWorkspaceParam = /* @__PURE__ */ __name((req, res) => {
    const workspaceCwd = req.params["id"] ?? "";
    if (!path11.isAbsolute(workspaceCwd)) {
      res.status(400).json({ error: "`:id` must decode to an absolute workspace path" });
      return null;
    }
    const key = canonicalizeWorkspace(workspaceCwd);
    if (key !== boundWorkspace) {
      sendWorkspaceMismatch2(res, key);
      return null;
    }
    return key;
  }, "resolveWorkspaceParam");
  const withMutableSession = /* @__PURE__ */ __name((route, handler) => async (req, res) => {
    const sessionId = requireSessionId(req, res);
    if (sessionId === null) return;
    const runtime = resolveLiveSessionRuntime(sessionId, res, route);
    if (!runtime) return;
    if (!runtime.primary) {
      sendNonPrimarySessionRouteUnsupported(res, route, sessionId, runtime);
      return;
    }
    try {
      await archiveCoordinator.runSharedMany([sessionId], async () => {
        await handler(req, res, sessionId);
      });
    } catch (err) {
      sendBridgeError2(res, err, { route, sessionId });
    }
  }, "withMutableSession");
  app.post("/session", mutate(), async (req, res) => {
    const body = safeBody(req);
    const resolvedRuntime = resolveRuntimeForSessionCreation(body, res);
    if (resolvedRuntime === void 0) return;
    const { runtime, workspaceCwd } = resolvedRuntime;
    const modelServiceId = typeof body["modelServiceId"] === "string" ? body["modelServiceId"] : void 0;
    const rawSessionScope = body["sessionScope"];
    let sessionScope;
    if (rawSessionScope !== void 0) {
      if (rawSessionScope !== "single" && rawSessionScope !== "thread") {
        res.status(400).json({
          error: '`sessionScope` must be "single" or "thread" when provided',
          code: "invalid_session_scope"
        });
        return;
      }
      sessionScope = rawSessionScope;
    }
    const approvalMode = parseOptionalApprovalMode(body, res);
    if (approvalMode === null) return;
    const source = parseSessionSource(body["sourceType"], body["sourceId"]);
    if ("error" in source) {
      res.status(400).json({
        error: source.error,
        code: "invalid_session_source"
      });
      return;
    }
    const clientId = parseClientIdHeader(req, res);
    if (clientId === null) return;
    try {
      const session = await runtime.bridge.spawnOrAttach({
        workspaceCwd,
        modelServiceId,
        ...clientId !== void 0 ? { clientId } : {},
        ...sessionScope !== void 0 ? { sessionScope } : {},
        ...approvalMode !== void 0 ? { approvalMode } : {},
        ...source.sourceType !== void 0 ? { sourceType: source.sourceType } : {},
        ...source.sourceId !== void 0 ? { sourceId: source.sourceId } : {}
      });
      if (daemonLog) {
        daemonLog.info(
          session.attached ? "session attached" : "session spawned",
          { sessionId: session.sessionId, clientId: session.clientId }
        );
      }
      if (!res.writable) {
        if (daemonLog) {
          daemonLog.warn(
            "session reaped (client disconnected before response)",
            {
              sessionId: session.sessionId,
              attached: session.attached
            }
          );
        }
        if (!session.attached) {
          try {
            const killed = await runtime.bridge.killSession(session.sessionId, {
              requireZeroAttaches: true
            });
            if (killed) {
              await new SessionService(runtime.workspaceCwd).removeSession(
                session.sessionId
              );
            }
          } catch {
          }
        } else {
          runtime.bridge.detachClient(session.sessionId, session.clientId).catch(() => {
          });
        }
        return;
      }
      res.status(200).json(session);
    } catch (err) {
      sendBridgeError2(res, err, { route: "POST /session" });
    }
  });
  const restoreSessionHandler = /* @__PURE__ */ __name((action) => async (req, res) => {
    const sessionId = requireSessionId(req, res);
    if (!sessionId) return;
    const body = safeBody(req);
    const route = `POST /session/:id/${action}`;
    let resolvedRuntime;
    try {
      resolvedRuntime = resolveRuntimeForSessionRestore(
        body,
        res,
        route,
        sessionId
      );
    } catch (err) {
      sendBridgeError2(res, err, { route, sessionId });
      return;
    }
    if (resolvedRuntime === void 0) return;
    const { runtime, workspaceCwd } = resolvedRuntime;
    const releaseRestoreOwner = enterRestoreOwner(
      res,
      route,
      sessionId,
      runtime
    );
    if (!releaseRestoreOwner) return;
    const approvalMode = parseOptionalApprovalMode(body, res);
    if (approvalMode === null) {
      releaseRestoreOwner();
      return;
    }
    const clientId = parseClientIdHeader(req, res);
    if (clientId === null) {
      releaseRestoreOwner();
      return;
    }
    try {
      const session = await archiveCoordinator.runSharedMany(
        [sessionId],
        async () => {
          await assertSessionLoadable(workspaceCwd, sessionId);
          const metadata = await new SessionService(
            workspaceCwd
          ).readCreationMetadata(sessionId);
          return action === "load" ? await runtime.bridge.loadSession({
            sessionId,
            workspaceCwd,
            historyReplay: "response",
            ...clientId !== void 0 ? { clientId } : {},
            ...approvalMode !== void 0 ? { approvalMode } : {},
            ...metadata
          }) : await runtime.bridge.resumeSession({
            sessionId,
            workspaceCwd,
            ...clientId !== void 0 ? { clientId } : {},
            ...approvalMode !== void 0 ? { approvalMode } : {},
            ...metadata
          });
        }
      );
      if (daemonLog) {
        daemonLog.info(
          `session ${action}${session.attached ? " (attached)" : ""}`,
          { sessionId: session.sessionId, clientId: session.clientId }
        );
      }
      if (!res.writable) {
        if (!session.attached) {
          runtime.bridge.killSession(session.sessionId, { requireZeroAttaches: true }).catch(() => {
          });
        } else {
          runtime.bridge.detachClient(session.sessionId, session.clientId).catch(() => {
          });
        }
        return;
      }
      res.status(200).json(session);
    } catch (err) {
      sendBridgeError2(res, err, {
        route,
        sessionId
      });
    } finally {
      releaseRestoreOwner();
    }
  }, "restoreSessionHandler");
  app.post("/session/:id/load", mutate(), restoreSessionHandler("load"));
  app.post("/session/:id/resume", mutate(), restoreSessionHandler("resume"));
  app.post(
    "/session/:id/branch",
    mutate(),
    withMutableSession(
      "POST /session/:id/branch",
      async (req, res, sessionId) => {
        const body = safeBody(req);
        let name = typeof body?.["name"] === "string" ? body["name"] : void 0;
        if (name) {
          name = name.replace(/[\x00-\x1F\x7F-\x9F]/g, "");
          if (name.length > 200) {
            name = name.slice(0, 200);
          }
        }
        const clientId = parseClientIdHeader(req, res);
        if (clientId === null) return;
        const result = await bridge.branchSession(
          sessionId,
          { name },
          { clientId }
        );
        if (!res.writable) {
          if (!result.attached) {
            bridge.killSession(result.sessionId, { requireZeroAttaches: true }).catch(() => {
            });
          } else {
            bridge.detachClient(result.sessionId, result.clientId).catch(() => {
            });
          }
          return;
        }
        res.status(201).json(result);
      }
    )
  );
  app.post(
    "/session/:id/fork",
    mutate(),
    withMutableSession(
      "POST /session/:id/fork",
      async (req, res, sessionId) => {
        const body = safeBody(req);
        const directive = body["directive"];
        if (typeof directive !== "string" || directive.trim().length === 0) {
          res.status(400).json({
            error: "`directive` is required and must be a non-empty string",
            code: "missing_directive"
          });
          return;
        }
        const clientId = parseClientIdHeader(req, res);
        if (clientId === null) return;
        const result = await bridge.launchSessionForkAgent(
          sessionId,
          directive,
          clientId !== void 0 ? { clientId } : void 0
        );
        res.status(202).json(result);
      }
    )
  );
  app.post(
    "/session/:id/cd",
    mutate(),
    withMutableSession("POST /session/:id/cd", async (req, res, sessionId) => {
      const body = safeBody(req);
      const targetPath = body["path"];
      if (typeof targetPath !== "string" || targetPath.length === 0 || !path11.isAbsolute(targetPath)) {
        res.status(400).json({
          error: "`path` is required and must be an absolute path",
          code: "invalid_path"
        });
        return;
      }
      const clientId = parseClientIdHeader(req, res);
      if (clientId === null) return;
      const result = await bridge.changeSessionCwd(
        sessionId,
        { path: targetPath },
        clientId !== void 0 ? { clientId } : void 0
      );
      res.status(200).json(result);
    })
  );
  app.get("/session/:id/status", (req, res) => {
    const sessionId = requireSessionId(req, res);
    if (sessionId === null) return;
    const runtime = resolveLiveSessionRuntime(
      sessionId,
      res,
      "GET /session/:id/status"
    );
    if (!runtime) return;
    try {
      res.status(200).json(runtime.bridge.getSessionSummary(sessionId));
    } catch (err) {
      sendBridgeError2(res, err, {
        route: "GET /session/:id/status",
        sessionId
      });
    }
  });
  app.get("/session/:id/export", async (req, res) => {
    await handleSessionExport(req, res, {
      route: "GET /session/:id/export",
      workspaceCwd: boundWorkspace
    });
  });
  app.get("/workspaces/:workspace/session/:id/export", async (req, res) => {
    const route = "GET /workspaces/:workspace/session/:id/export";
    const runtime = requireTrustedRuntimeForWorkspaceRoute(req, res, route);
    if (!runtime) return;
    await handleSessionExport(req, res, {
      route,
      workspaceCwd: runtime.workspaceCwd,
      workspaceQualified: true
    });
  });
  app.get(
    "/workspaces/:workspace/session/:id/archive/export",
    async (req, res) => {
      const route = "GET /workspaces/:workspace/session/:id/archive/export";
      const runtime = requireTrustedRuntimeForWorkspaceRoute(req, res, route);
      if (!runtime) return;
      await handleSessionExport(req, res, {
        route,
        workspaceCwd: runtime.workspaceCwd,
        workspaceQualified: true,
        archiveState: "archived"
      });
    }
  );
  app.get("/session/:id/transcript", async (req, res) => {
    const route = "GET /session/:id/transcript";
    const sessionId = requireSessionId(req, res);
    if (sessionId === null) return;
    const limit = parseTranscriptLimitQuery(req.query["limit"], res);
    if (limit === null) return;
    const cursor = parseTranscriptCursorQuery(req.query["cursor"], res);
    if (cursor === null) return;
    try {
      const result = await archiveCoordinator.runSharedMany(
        [sessionId],
        async () => {
          const runtime = await resolveTranscriptSessionRuntime(
            res,
            route,
            sessionId,
            cursor !== void 0
          );
          if (!runtime) return void 0;
          return runtime.bridge.getSessionTranscriptPage({
            sessionId,
            ...limit !== void 0 ? { limit } : {},
            ...cursor !== void 0 ? { cursor } : {}
          });
        }
      );
      if (result === void 0) return;
      res.status(200).set("Cache-Control", "no-store").json(result);
    } catch (err) {
      sendBridgeError2(res, err, {
        route,
        sessionId
      });
    }
  });
  app.get("/workspaces/:workspace/session/:id/transcript", async (req, res) => {
    const route = "GET /workspaces/:workspace/session/:id/transcript";
    const sessionId = requireSessionId(req, res);
    if (sessionId === null) return;
    const runtime = resolveWorkspaceRuntimeFromParam(
      workspaceRegistry,
      req,
      res
    );
    if (!runtime) return;
    if (!runtime.trusted && runtime.primary) {
      sendUntrustedWorkspaceResponse(res, {
        sessionId,
        workspaceCwd: runtime.workspaceCwd,
        workspaceId: runtime.workspaceId
      });
      return;
    }
    const limit = parseTranscriptLimitQuery(req.query["limit"], res);
    if (limit === null) return;
    const cursor = parseTranscriptCursorQuery(req.query["cursor"], res);
    if (cursor === null) return;
    if (cursor !== void 0 && workspaceTranscriptCursorExceedsLimit(cursor)) {
      res.status(400).json({
        error: "`cursor` exceeds the maximum size",
        code: "invalid_transcript_cursor"
      });
      return;
    }
    try {
      const result = await runWithoutDebugLogSession(
        () => archiveCoordinator.runSharedMany([sessionId], async () => {
          const service = new SessionService(runtime.workspaceCwd);
          if (cursor === void 0) {
            await assertSessionLoadable(runtime.workspaceCwd, sessionId);
          }
          const codec = getTranscriptCursorCodec(runtime);
          const reader = new SessionTranscriptReader(
            runtime.workspaceCwd,
            codec
          );
          let page;
          try {
            page = await reader.readPage(sessionId, {
              ...limit !== void 0 ? { limit } : {},
              ...cursor !== void 0 ? { cursor } : {},
              maxBytes: WORKSPACE_TRANSCRIPT_PAGE_SOURCE_MAX_BYTES
            });
          } catch (error2) {
            if (error2.code !== "ENOENT") {
              throw error2;
            }
            if (cursor !== void 0) {
              throw new SessionTranscriptSnapshotUnavailableError(sessionId);
            }
            const location = await service.getSessionLocation(sessionId);
            if (location === "archived") {
              throw new SessionArchivedError(sessionId);
            }
            if (location === "conflict") {
              throw new SessionConflictError(sessionId);
            }
            throw new SessionNotFoundError(sessionId);
          }
          if (page.records.some((record) => record.sessionId !== sessionId)) {
            throw new SessionTranscriptSnapshotUnavailableError(sessionId);
          }
          const replay = await replayTranscriptRecordPage({
            sessionId,
            page,
            encodeCursor: /* @__PURE__ */ __name((state) => codec.encode(state), "encodeCursor")
          });
          const cursorTooLarge = replay.nextCursor !== void 0 && Buffer.byteLength(replay.nextCursor) > WORKSPACE_TRANSCRIPT_CURSOR_MAX_BYTES;
          return {
            v: 1,
            sessionId,
            events: replay.updates.map((update) => ({
              v: 1,
              type: "session_update",
              data: update
            })),
            ...replay.nextCursor && !cursorTooLarge ? { nextCursor: replay.nextCursor } : {},
            hasMore: cursorTooLarge ? false : replay.hasMore,
            startTime: replay.startTime,
            lastUpdated: replay.lastUpdated,
            ...replay.partial || cursorTooLarge ? {
              partial: true,
              replayError: cursorTooLarge ? TRANSCRIPT_CURSOR_TOO_LARGE_REPLAY_ERROR : replay.replayError
            } : {}
          };
        })
      );
      const serialized = serializeWorkspaceTranscriptResponse(
        result,
        sessionId
      );
      res.status(200).set("Cache-Control", "no-store").type("application/json").send(serialized);
    } catch (err) {
      sendBridgeError2(res, err, { route, sessionId });
    }
  });
  app.get(
    "/session/:id/context",
    withOwnerReadSession(
      "GET /session/:id/context",
      async (_req, res, sessionId, runtime) => {
        res.status(200).json(await runtime.bridge.getSessionContextStatus(sessionId));
      }
    )
  );
  app.get(
    "/session/:id/context-usage",
    withOwnerReadSession(
      "GET /session/:id/context-usage",
      async (req, res, sessionId, runtime) => {
        res.status(200).json(
          await runtime.bridge.getSessionContextUsageStatus(sessionId, {
            detail: req.query["detail"] === "true"
          })
        );
      }
    )
  );
  app.get(
    "/session/:id/stats",
    withOwnerReadSession(
      "GET /session/:id/stats",
      async (_req, res, sessionId, runtime) => {
        res.status(200).json(await runtime.bridge.getSessionStatsStatus(sessionId));
      }
    )
  );
  app.get(
    "/session/:id/supported-commands",
    withOwnerReadSession(
      "GET /session/:id/supported-commands",
      async (_req, res, sessionId, runtime) => {
        res.status(200).json(
          await runtime.bridge.getSessionSupportedCommandsStatus(sessionId)
        );
      }
    )
  );
  app.get(
    "/session/:id/tasks",
    withOwnerReadSession(
      "GET /session/:id/tasks",
      async (_req, res, sessionId, runtime) => {
        res.status(200).json(await runtime.bridge.getSessionTasksStatus(sessionId));
      }
    )
  );
  app.get(
    "/session/:id/lsp",
    withOwnerReadSession(
      "GET /session/:id/lsp",
      async (_req, res, sessionId, runtime) => {
        res.status(200).json(await runtime.bridge.getSessionLspStatus(sessionId));
      }
    )
  );
  app.get(
    "/session/:id/hooks",
    withOwnerReadSession(
      "GET /session/:id/hooks",
      async (_req, res, sessionId, runtime) => {
        res.status(200).json(await runtime.bridge.getSessionHooksStatus(sessionId));
      }
    )
  );
  app.get(
    "/session/:id/artifacts",
    withOwnerReadSession(
      "GET /session/:id/artifacts",
      async (req, res, sessionId, runtime) => {
        const clientId = parseClientIdHeader(req, res);
        if (clientId === null) return;
        res.status(200).json(
          await runtime.bridge.getSessionArtifacts(
            sessionId,
            clientId !== void 0 ? { clientId } : void 0
          )
        );
      }
    )
  );
  app.post(
    "/session/:id/artifacts",
    mutate({ strict: true }),
    withOwnerMutableSession(
      "POST /session/:id/artifacts",
      async (req, res, sessionId, runtime) => {
        const clientId = parseClientIdHeader(req, res);
        if (clientId === null) return;
        if (!requireSessionArtifactClientId(clientId, res)) return;
        try {
          const body = safeBody(req);
          const artifact = {
            title: body["title"],
            kind: body["kind"],
            storage: body["storage"],
            description: body["description"],
            workspacePath: body["workspacePath"],
            managedId: body["managedId"],
            url: body["url"],
            mimeType: body["mimeType"],
            sizeBytes: body["sizeBytes"],
            metadata: body["metadata"],
            retention: body["retention"],
            clientRetained: body["clientRetained"]
          };
          const result = await runtime.bridge.addSessionArtifact(
            sessionId,
            artifact,
            { clientId }
          );
          res.status(200).json(result);
        } catch (err) {
          if (sendArtifactValidationError(res, err)) return;
          sendBridgeError2(res, err, {
            route: "POST /session/:id/artifacts",
            sessionId
          });
        }
      }
    )
  );
  app.delete(
    "/session/:id/artifacts/:artifactId",
    mutate({ strict: true }),
    withOwnerMutableSession(
      "DELETE /session/:id/artifacts/:artifactId",
      async (req, res, sessionId, runtime) => {
        const artifactId = req.params["artifactId"];
        const clientId = parseClientIdHeader(req, res);
        if (clientId === null) return;
        if (!requireSessionArtifactClientId(clientId, res)) return;
        if (!artifactId) {
          res.status(400).json({
            v: 1,
            error: {
              code: "VALIDATION_FAILED",
              message: "`artifactId` route parameter is required",
              field: "artifactId"
            }
          });
          return;
        }
        try {
          const result = await runtime.bridge.removeSessionArtifact(
            sessionId,
            artifactId,
            { clientId }
          );
          res.status(200).json(result);
        } catch (err) {
          if (sendArtifactValidationError(res, err)) return;
          sendBridgeError2(res, err, {
            route: "DELETE /session/:id/artifacts/:artifactId",
            sessionId
          });
        }
      }
    )
  );
  app.post(
    "/session/:id/tasks/:taskId/cancel",
    mutate({ strict: true }),
    withOwnerMutableSession(
      "POST /session/:id/tasks/:taskId/cancel",
      async (req, res, sessionId, runtime) => {
        const taskId = req.params["taskId"];
        if (!taskId) {
          res.status(400).json({
            error: "`taskId` route parameter is required"
          });
          return;
        }
        const body = safeBody(req);
        const kind = body["kind"];
        if (kind !== "agent" && kind !== "shell" && kind !== "monitor") {
          res.status(400).json({ error: '`kind` must be "agent", "shell", or "monitor"' });
          return;
        }
        res.status(200).json(
          await runtime.bridge.cancelSessionTask(sessionId, taskId, kind)
        );
      }
    )
  );
  app.post(
    "/session/:id/goal/clear",
    mutate({ strict: true }),
    withOwnerMutableSession(
      "POST /session/:id/goal/clear",
      async (_req, res, sessionId, runtime) => {
        res.status(200).json(await runtime.bridge.clearSessionGoal(sessionId));
      }
    )
  );
  app.post(
    "/session/:id/continue",
    mutate({ strict: true }),
    withOwnerMutableSession(
      "POST /session/:id/continue",
      async (req, res, sessionId, runtime) => {
        const clientId = parseClientIdHeader(req, res);
        if (clientId === null) return;
        const promptId = crypto3.randomUUID();
        res.status(200).json(
          await runtime.bridge.continueSession(sessionId, {
            ...clientId !== void 0 ? { clientId } : {},
            promptId
          })
        );
      }
    )
  );
  app.post(
    "/session/:id/prompt",
    mutate(),
    withOwnerMutableSession(
      "POST /session/:id/prompt",
      async (req, res, sessionId, runtime) => {
        const ownerBridge = runtime.bridge;
        const body = safeBody(req);
        const prompt = body["prompt"];
        if (!Array.isArray(prompt) || prompt.length === 0) {
          res.status(400).json({
            error: "`prompt` is required and must be a non-empty array of content blocks"
          });
          return;
        }
        if (!prompt.every(
          (item) => typeof item === "object" && item !== null && !Array.isArray(item)
        )) {
          res.status(400).json({
            error: "each `prompt` element must be an object (content block)"
          });
          return;
        }
        const rawRequestDeadline = body["deadlineMs"];
        let requestDeadlineMs;
        if (rawRequestDeadline !== void 0 && rawRequestDeadline !== null) {
          if (typeof rawRequestDeadline !== "number" || !Number.isFinite(rawRequestDeadline) || !Number.isInteger(rawRequestDeadline) || rawRequestDeadline <= 0) {
            res.status(400).json({
              error: "`deadlineMs` must be a positive integer (milliseconds)",
              code: "invalid_deadline_ms"
            });
            return;
          }
          requestDeadlineMs = rawRequestDeadline;
        }
        const clientId = parseClientIdHeader(req, res);
        if (clientId === null) return;
        const promptId = crypto3.randomUUID();
        const forwardedBody = { ...body };
        delete forwardedBody["deadlineMs"];
        const lastEventId = ownerBridge.getSessionLastEventId(sessionId);
        addDaemonRequestAttribute("qwen-code.prompt_id", promptId);
        const abort = new AbortController();
        let responseFinished = false;
        const onResClose = /* @__PURE__ */ __name(() => {
          if (!responseFinished) abort.abort();
        }, "onResClose");
        const onResFinish = /* @__PURE__ */ __name(() => {
          responseFinished = true;
          res.off("close", onResClose);
        }, "onResFinish");
        res.once("close", onResClose);
        res.once("finish", onResFinish);
        const effectiveDeadlineMs = resolvePromptDeadlineMs(
          promptDeadlineMs,
          requestDeadlineMs
        );
        let deadlineTimer;
        if (effectiveDeadlineMs !== void 0) {
          deadlineTimer = setTimeout(() => {
            if (!abort.signal.aborted) {
              abort.abort(new PromptDeadlineExceededError(effectiveDeadlineMs));
            }
          }, effectiveDeadlineMs);
          deadlineTimer.unref();
        }
        let promptPromise;
        try {
          promptPromise = ownerBridge.sendPrompt(
            sessionId,
            {
              ...forwardedBody,
              sessionId,
              prompt
            },
            abort.signal,
            {
              ...clientId !== void 0 ? { clientId } : {},
              promptId
            }
          );
        } catch (err) {
          if (deadlineTimer !== void 0) clearTimeout(deadlineTimer);
          res.off("close", onResClose);
          res.off("finish", onResFinish);
          if (daemonLog && err instanceof PromptQueueFullError) {
            daemonLog.warn("prompt admission rejected: queue full", {
              sessionId,
              promptId,
              ...clientId !== void 0 ? { clientId } : {},
              limit: err.limit,
              pendingCount: err.pendingCount
            });
          }
          if (daemonLog && err instanceof InvalidClientIdError) {
            daemonLog.warn("prompt admission rejected: invalid client id", {
              sessionId,
              promptId,
              ...clientId !== void 0 ? { clientId } : {}
            });
          }
          sendBridgeError2(res, err, {
            route: "POST /session/:id/prompt",
            sessionId
          });
          return;
        }
        res.off("close", onResClose);
        promptPromise.then(
          () => {
            if (daemonLog) {
              daemonLog.info("prompt turn completed", {
                sessionId,
                promptId,
                clientId
              });
            }
          },
          (err) => {
            if (daemonLog) {
              const errName = err instanceof Error ? err.name : void 0;
              daemonLog.warn(
                `prompt turn failed: ${errName ? `[${errName}] ` : ""}${err instanceof Error ? err.message : String(err)}`,
                { sessionId, promptId, clientId }
              );
            }
          }
        ).finally(() => {
          if (deadlineTimer !== void 0) clearTimeout(deadlineTimer);
        }).catch(() => {
        });
        if (daemonLog) {
          daemonLog.info("prompt enqueued", { sessionId, promptId, clientId });
        }
        res.status(202).json({ promptId, lastEventId });
      }
    )
  );
  app.post(
    "/session/:id/generate",
    mutate(),
    withOwnerReadSession(
      "POST /session/:id/generate",
      async (req, res, sessionId, runtime) => {
        const body = safeBody(req);
        const prompt = body["prompt"];
        if (typeof prompt !== "string" || prompt.trim().length === 0 || Buffer.byteLength(prompt, "utf8") > GENERATION_MAX_PROMPT_BYTES) {
          res.status(400).json({
            error: `\`prompt\` must be a non-empty string no larger than ${GENERATION_MAX_PROMPT_BYTES} UTF-8 bytes`,
            code: "invalid_prompt"
          });
          return;
        }
        const clientId = parseClientIdHeader(req, res);
        if (clientId === null) return;
        if (!runtime.bridge.generateSessionContent) {
          res.status(501).json({
            error: "Stateless generation is not supported by this bridge",
            code: "generation_not_supported"
          });
          return;
        }
        const abort = new AbortController();
        let completed = false;
        const onClose = /* @__PURE__ */ __name(() => {
          if (!completed) abort.abort();
        }, "onClose");
        res.once("close", onClose);
        const stream = runtime.bridge.generateSessionContent(
          sessionId,
          prompt,
          abort.signal,
          clientId !== void 0 ? { clientId } : void 0
        );
        res.status(200);
        res.setHeader("Content-Type", "text/event-stream");
        res.setHeader("Cache-Control", "no-cache, no-transform");
        res.setHeader("Connection", "keep-alive");
        res.setHeader("X-Accel-Buffering", "no");
        res.flushHeaders();
        let writeChain = Promise.resolve();
        const write = /* @__PURE__ */ __name((chunk) => {
          writeChain = writeChain.then(
            () => writeGenerationSseChunk(res, chunk)
          );
          return writeChain;
        }, "write");
        await write(": connected\n\n");
        const heartbeat = setInterval(() => {
          void write(": heartbeat\n\n").catch(() => abort.abort());
        }, GENERATION_HEARTBEAT_MS);
        heartbeat.unref();
        try {
          for await (const event of stream) {
            await write(formatGenerationSse(event.type, event));
          }
        } catch (err) {
          if (!abort.signal.aborted && !res.destroyed) {
            daemonLog?.error(
              "session generation failed",
              err instanceof Error ? err : new Error(String(err)),
              { sessionId, clientId }
            );
            await write(
              formatGenerationSse("error", {
                type: "error",
                code: "generation_failed",
                message: "Generation failed"
              })
            ).catch(() => void 0);
          }
        } finally {
          completed = true;
          clearInterval(heartbeat);
          res.off("close", onClose);
          if (!res.destroyed) res.end();
        }
      }
    )
  );
  app.post(
    "/session/:id/heartbeat",
    mutate(),
    withOwnerMutableSession(
      "POST /session/:id/heartbeat",
      (req, res, sessionId, runtime) => {
        const clientId = parseClientIdHeader(req, res);
        if (clientId === null) return;
        const result = runtime.bridge.recordHeartbeat(
          sessionId,
          clientId !== void 0 ? { clientId } : void 0
        );
        res.status(200).json(result);
      }
    )
  );
  app.post(
    "/session/:id/detach",
    mutate(),
    withOwnerMutableSession(
      "POST /session/:id/detach",
      async (req, res, sessionId, runtime) => {
        const clientId = parseClientIdHeader(req, res);
        if (clientId === null) return;
        await runtime.bridge.detachClient(sessionId, clientId);
        res.status(204).end();
      }
    )
  );
  app.post(
    "/session/:id/cancel",
    mutate(),
    withOwnerMutableSession(
      "POST /session/:id/cancel",
      async (req, res, sessionId, runtime) => {
        const body = safeBody(req);
        const clientId = parseClientIdHeader(req, res);
        if (clientId === null) return;
        await runtime.bridge.cancelSession(
          sessionId,
          {
            ...body,
            sessionId
          },
          clientId !== void 0 ? { clientId } : void 0
        );
        if (daemonLog) {
          daemonLog.info("cancel sent", { sessionId, clientId });
        }
        res.status(204).end();
      }
    )
  );
  app.delete("/session/:id", async (req, res) => {
    const sessionId = req.params["id"];
    const clientId = parseClientIdHeader(req, res);
    if (clientId === null) return;
    const runtime = resolveLiveSessionRuntime(
      sessionId,
      res,
      "DELETE /session/:id"
    );
    if (!runtime) return;
    try {
      await archiveCoordinator.runExclusiveMany(
        [sessionId],
        async () => runtime.bridge.closeSession(
          sessionId,
          clientId !== void 0 ? { clientId } : void 0
        )
      );
      res.status(204).end();
    } catch (err) {
      sendBridgeError2(res, err, {
        route: "DELETE /session/:id",
        sessionId
      });
    }
  });
  app.post("/sessions/delete", mutate(), async (req, res) => {
    const clientId = parseClientIdHeader(req, res);
    if (clientId === null) return;
    const uniqueIds = parseSessionIdsBody(req, res);
    if (uniqueIds === void 0) return;
    try {
      const service = new SessionService(boundWorkspace);
      const result = await deleteDaemonSessions({
        sessionIds: uniqueIds,
        service,
        bridge,
        coordinator: archiveCoordinator,
        onError: /* @__PURE__ */ __name(({ phase, sessionId, error: error2 }) => {
          writeStderrLine(
            `qwen serve: ${phase}Session failed for ${safeLogValue(sessionId)}: ${safeLogValue(error2)}`
          );
        }, "onError")
      });
      res.status(200).json(result);
    } catch (err) {
      sendBridgeError2(res, err, { route: "POST /sessions/delete" });
    }
  });
  app.post("/sessions/archive", mutate(), async (req, res) => {
    const uniqueIds = parseSessionIdsBody(req, res);
    if (uniqueIds === void 0) return;
    const service = new SessionService(boundWorkspace, {
      onWarning: logSessionArchiveWarning
    });
    try {
      const result = await archiveDaemonSessions({
        sessionIds: uniqueIds,
        service,
        bridge,
        coordinator: archiveCoordinator
      });
      res.status(200).json({
        archived: result.archived,
        alreadyArchived: result.alreadyArchived,
        notFound: result.notFound,
        errors: serializeSessionErrors(result.errors)
      });
    } catch (err) {
      sendBridgeError2(res, err, { route: "POST /sessions/archive" });
    }
  });
  app.post("/sessions/unarchive", mutate(), async (req, res) => {
    const uniqueIds = parseSessionIdsBody(req, res);
    if (uniqueIds === void 0) return;
    const service = new SessionService(boundWorkspace, {
      onWarning: logSessionArchiveWarning
    });
    try {
      const result = await unarchiveDaemonSessions({
        sessionIds: uniqueIds,
        service,
        coordinator: archiveCoordinator
      });
      res.status(200).json({
        unarchived: result.unarchived,
        alreadyActive: result.alreadyActive,
        notFound: result.notFound,
        errors: serializeSessionErrors(result.errors)
      });
    } catch (err) {
      sendBridgeError2(res, err, { route: "POST /sessions/unarchive" });
    }
  });
  app.post(
    "/workspaces/:workspace/sessions/delete",
    mutate(),
    async (req, res) => {
      const route = "POST /workspaces/:workspace/sessions/delete";
      const runtime = requireTrustedRuntimeForWorkspaceRoute(req, res, route);
      if (!runtime) return;
      const clientId = parseClientIdHeader(req, res);
      if (clientId === null) return;
      const uniqueIds = parseSessionIdsBody(req, res);
      if (uniqueIds === void 0) return;
      try {
        const service = new SessionService(runtime.workspaceCwd);
        const result = await deleteDaemonSessions({
          sessionIds: uniqueIds,
          service,
          bridge: runtime.bridge,
          coordinator: archiveCoordinator,
          onError: /* @__PURE__ */ __name(({ phase, sessionId, error: error2 }) => {
            writeStderrLine(
              `qwen serve: ${phase}Session failed for ${safeLogValue(sessionId)}: ${safeLogValue(error2)}`
            );
          }, "onError")
        });
        res.status(200).json(result);
      } catch (err) {
        sendBridgeError2(res, err, { route });
      }
    }
  );
  app.post(
    "/workspaces/:workspace/sessions/archive",
    mutate(),
    async (req, res) => {
      const route = "POST /workspaces/:workspace/sessions/archive";
      const runtime = requireTrustedRuntimeForWorkspaceRoute(req, res, route);
      if (!runtime) return;
      const uniqueIds = parseSessionIdsBody(req, res);
      if (uniqueIds === void 0) return;
      const service = new SessionService(runtime.workspaceCwd, {
        onWarning: logSessionArchiveWarning
      });
      try {
        const result = await archiveDaemonSessions({
          sessionIds: uniqueIds,
          service,
          bridge: runtime.bridge,
          coordinator: archiveCoordinator
        });
        res.status(200).json({
          archived: result.archived,
          alreadyArchived: result.alreadyArchived,
          notFound: result.notFound,
          errors: serializeSessionErrors(result.errors)
        });
      } catch (err) {
        sendBridgeError2(res, err, { route });
      }
    }
  );
  app.post(
    "/workspaces/:workspace/sessions/unarchive",
    mutate(),
    async (req, res) => {
      const route = "POST /workspaces/:workspace/sessions/unarchive";
      const runtime = requireTrustedRuntimeForWorkspaceRoute(req, res, route);
      if (!runtime) return;
      const uniqueIds = parseSessionIdsBody(req, res);
      if (uniqueIds === void 0) return;
      const service = new SessionService(runtime.workspaceCwd, {
        onWarning: logSessionArchiveWarning
      });
      try {
        const result = await unarchiveDaemonSessions({
          sessionIds: uniqueIds,
          service,
          coordinator: archiveCoordinator
        });
        res.status(200).json({
          unarchived: result.unarchived,
          alreadyActive: result.alreadyActive,
          notFound: result.notFound,
          errors: serializeSessionErrors(result.errors)
        });
      } catch (err) {
        sendBridgeError2(res, err, { route });
      }
    }
  );
  app.patch(
    "/session/:id/metadata",
    mutate({ strict: true }),
    withOwnerMutableSession(
      "PATCH /session/:id/metadata",
      (req, res, sessionId, runtime) => {
        const body = safeBody(req);
        const clientId = parseClientIdHeader(req, res);
        if (clientId === null) return;
        const rawDisplayName = body["displayName"];
        if (rawDisplayName !== void 0 && typeof rawDisplayName !== "string") {
          res.status(400).json({
            error: "`displayName` must be a string",
            code: "invalid_metadata",
            field: "displayName"
          });
          return;
        }
        const displayName = typeof rawDisplayName === "string" ? rawDisplayName.slice(0, 256) : void 0;
        const effective = runtime.bridge.updateSessionMetadata(
          sessionId,
          { displayName },
          clientId !== void 0 ? { clientId } : void 0
        );
        res.status(200).json({ sessionId, ...effective });
      }
    )
  );
  const handleSessionOrganizationUpdate = /* @__PURE__ */ __name(async (req, res, target) => {
    const sessionId = requireSessionId(req, res);
    if (sessionId === null) return;
    try {
      await archiveCoordinator.runSharedMany([sessionId], async () => {
        const sessionService = new SessionService(target.workspaceCwd);
        let exists = await sessionService.sessionExistsInAnyState(sessionId);
        if (!exists) {
          try {
            const summary = target.bridge.getSessionSummary(sessionId);
            exists = summary.workspaceCwd === target.workspaceCwd;
          } catch {
            exists = false;
          }
        }
        if (!exists) {
          res.status(404).json({
            error: `No session with id "${sessionId}"`,
            sessionId
          });
          return;
        }
        const body = safeBody(req);
        const rawIsPinned = body["isPinned"];
        if (rawIsPinned !== void 0 && typeof rawIsPinned !== "boolean") {
          res.status(400).json({
            error: "`isPinned` must be a boolean",
            code: "invalid_session_organization",
            field: "isPinned"
          });
          return;
        }
        const rawGroupId = body["groupId"];
        if (rawGroupId !== void 0 && rawGroupId !== null && typeof rawGroupId !== "string") {
          res.status(400).json({
            error: "`groupId` must be a string or null",
            code: "invalid_session_organization",
            field: "groupId"
          });
          return;
        }
        const rawColor = body["color"];
        if (rawColor !== void 0 && rawColor !== null && (typeof rawColor !== "string" || !GROUP_COLOR_OPTIONS.includes(rawColor))) {
          res.status(400).json({
            error: "`color` must be a supported color or null",
            code: "invalid_session_organization",
            field: "color"
          });
          return;
        }
        const organization = await createSessionOrganizationService(
          target.workspaceCwd
        ).updateSessionOrganization(sessionId, {
          ...rawIsPinned !== void 0 ? { isPinned: rawIsPinned } : {},
          ...rawGroupId !== void 0 ? { groupId: rawGroupId } : {},
          ...rawColor !== void 0 ? { color: rawColor } : {}
        });
        res.status(200).json({ sessionId, ...organization });
      });
    } catch (err) {
      if (sendSessionOrganizationError(res, err)) return;
      sendBridgeError2(res, err, {
        route: target.route,
        sessionId,
        workspaceCwd: target.workspaceCwd
      });
    }
  }, "handleSessionOrganizationUpdate");
  app.patch("/session/:id/organization", mutate(), async (req, res) => {
    await handleSessionOrganizationUpdate(req, res, {
      workspaceCwd: boundWorkspace,
      bridge,
      route: "PATCH /session/:id/organization"
    });
  });
  app.patch(
    "/workspaces/:workspace/session/:id/organization",
    mutate(),
    async (req, res) => {
      const route = "PATCH /workspaces/:workspace/session/:id/organization";
      const runtime = requireTrustedRuntimeForWorkspaceRoute(req, res, route);
      if (!runtime) return;
      await handleSessionOrganizationUpdate(req, res, {
        workspaceCwd: runtime.workspaceCwd,
        bridge: runtime.bridge,
        route
      });
    }
  );
  app.get("/workspace/:id/session-groups", async (req, res) => {
    const runtime = resolveRuntimeFromWorkspaceParam(req, res);
    if (runtime === null) return;
    try {
      res.status(200).json(
        await runWorkspaceInspectionWithLogPolicy(
          runtime,
          () => createSessionOrganizationService(runtime.workspaceCwd).listGroups()
        )
      );
    } catch (err) {
      sendBridgeError2(res, err, {
        route: "GET /workspace/:id/session-groups"
      });
    }
  });
  app.post("/workspace/:id/session-groups", mutate(), async (req, res) => {
    const key = resolveWorkspaceParam(req, res);
    if (key === null) return;
    const body = safeBody(req);
    try {
      const group = await createSessionOrganizationService(key).createGroup({
        name: body["name"],
        color: body["color"]
      });
      res.status(201).json({ group });
    } catch (err) {
      if (sendSessionOrganizationError(res, err)) return;
      sendBridgeError2(res, err, {
        route: "POST /workspace/:id/session-groups"
      });
    }
  });
  app.patch(
    "/workspace/:id/session-groups/:groupId",
    mutate(),
    async (req, res) => {
      const key = resolveWorkspaceParam(req, res);
      if (key === null) return;
      const body = safeBody(req);
      try {
        const group = await createSessionOrganizationService(key).updateGroup(
          req.params["groupId"] ?? "",
          {
            ...Object.prototype.hasOwnProperty.call(body, "name") ? { name: body["name"] } : {},
            ...Object.prototype.hasOwnProperty.call(body, "color") ? { color: body["color"] } : {},
            ...Object.prototype.hasOwnProperty.call(body, "order") ? { order: body["order"] } : {}
          }
        );
        res.status(200).json({ group });
      } catch (err) {
        if (sendSessionOrganizationError(res, err)) return;
        sendBridgeError2(res, err, {
          route: "PATCH /workspace/:id/session-groups/:groupId"
        });
      }
    }
  );
  app.delete(
    "/workspace/:id/session-groups/:groupId",
    mutate(),
    async (req, res) => {
      const key = resolveWorkspaceParam(req, res);
      if (key === null) return;
      try {
        const deleted = await createSessionOrganizationService(key).deleteGroup(
          req.params["groupId"] ?? ""
        );
        res.status(200).json({ deleted });
      } catch (err) {
        if (sendSessionOrganizationError(res, err)) return;
        sendBridgeError2(res, err, {
          route: "DELETE /workspace/:id/session-groups/:groupId"
        });
      }
    }
  );
  app.get("/workspaces/:workspace/session-groups", async (req, res) => {
    const route = "GET /workspaces/:workspace/session-groups";
    const runtime = resolveRuntimeForCatalogRoute(req, res, "workspace", route);
    if (!runtime) return;
    try {
      res.status(200).json(
        await runWorkspaceInspectionWithLogPolicy(
          runtime,
          () => createSessionOrganizationService(runtime.workspaceCwd).listGroups()
        )
      );
    } catch (err) {
      sendBridgeError2(res, err, { route });
    }
  });
  app.post(
    "/workspaces/:workspace/session-groups",
    mutate(),
    async (req, res) => {
      const route = "POST /workspaces/:workspace/session-groups";
      const runtime = requireTrustedRuntimeForWorkspaceRoute(req, res, route);
      if (!runtime) return;
      const body = safeBody(req);
      try {
        const group = await createSessionOrganizationService(
          runtime.workspaceCwd
        ).createGroup({
          name: body["name"],
          color: body["color"]
        });
        res.status(201).json({ group });
      } catch (err) {
        if (sendSessionOrganizationError(res, err)) return;
        sendBridgeError2(res, err, { route });
      }
    }
  );
  app.patch(
    "/workspaces/:workspace/session-groups/:groupId",
    mutate(),
    async (req, res) => {
      const route = "PATCH /workspaces/:workspace/session-groups/:groupId";
      const runtime = requireTrustedRuntimeForWorkspaceRoute(req, res, route);
      if (!runtime) return;
      const body = safeBody(req);
      try {
        const group = await createSessionOrganizationService(
          runtime.workspaceCwd
        ).updateGroup(req.params["groupId"] ?? "", {
          ...Object.prototype.hasOwnProperty.call(body, "name") ? { name: body["name"] } : {},
          ...Object.prototype.hasOwnProperty.call(body, "color") ? { color: body["color"] } : {},
          ...Object.prototype.hasOwnProperty.call(body, "order") ? { order: body["order"] } : {}
        });
        res.status(200).json({ group });
      } catch (err) {
        if (sendSessionOrganizationError(res, err)) return;
        sendBridgeError2(res, err, { route });
      }
    }
  );
  app.delete(
    "/workspaces/:workspace/session-groups/:groupId",
    mutate(),
    async (req, res) => {
      const route = "DELETE /workspaces/:workspace/session-groups/:groupId";
      const runtime = requireTrustedRuntimeForWorkspaceRoute(req, res, route);
      if (!runtime) return;
      try {
        const deleted = await createSessionOrganizationService(
          runtime.workspaceCwd
        ).deleteGroup(req.params["groupId"] ?? "");
        res.status(200).json({ deleted });
      } catch (err) {
        if (sendSessionOrganizationError(res, err)) return;
        sendBridgeError2(res, err, { route });
      }
    }
  );
  const listWorkspaceSessionsHandler = /* @__PURE__ */ __name((paramName) => async (req, res) => {
    const route = paramName === "workspace" ? "GET /workspaces/:workspace/sessions" : "GET /workspace/:id/sessions";
    const runtime = resolveRuntimeForCatalogRoute(req, res, paramName, route);
    if (runtime === null) return;
    const key = runtime.workspaceCwd;
    const readOnlySecondary = isReadOnlyWorkspaceInspection(runtime);
    try {
      const cursor = typeof req.query["cursor"] === "string" ? req.query["cursor"] : void 0;
      const size = parseSessionPageSizeQuery(req.query["size"]);
      const rawView = req.query["view"];
      let view;
      if (rawView !== void 0) {
        if (rawView !== "organized") {
          res.status(400).json({
            error: '`view` must be "organized"',
            code: "invalid_session_view"
          });
          return;
        }
        view = "organized";
      }
      const group = typeof req.query["group"] === "string" ? req.query["group"] : void 0;
      if (group !== void 0 && view !== "organized") {
        res.status(400).json({
          error: "`group` requires `view=organized`",
          code: "invalid_session_group_filter"
        });
        return;
      }
      const rawArchiveState = req.query["archiveState"];
      let archiveState;
      if (rawArchiveState !== void 0) {
        if (typeof rawArchiveState !== "string" || rawArchiveState !== "active" && rawArchiveState !== "archived") {
          res.status(400).json({
            error: '`archiveState` must be "active" or "archived"',
            code: "invalid_archive_state"
          });
          return;
        }
        archiveState = rawArchiveState;
      }
      const rawParentSessionId = req.query["parentSessionId"];
      let parentSessionId;
      if (rawParentSessionId !== void 0) {
        if (typeof rawParentSessionId !== "string" || rawParentSessionId.length === 0) {
          res.status(400).json({
            error: "`parentSessionId` must be a non-empty string",
            code: "invalid_parent_session_id"
          });
          return;
        }
        if (view === "organized") {
          res.status(400).json({
            error: "`parentSessionId` is not supported with `view=organized`",
            code: "invalid_parent_session_filter"
          });
          return;
        }
        parentSessionId = rawParentSessionId;
      }
      const parsedSource = parseSessionSource(
        req.query["sourceType"],
        req.query["sourceId"]
      );
      if ("error" in parsedSource) {
        res.status(400).json({
          error: parsedSource.error,
          code: "invalid_session_source"
        });
        return;
      }
      const options = {
        ...cursor !== void 0 ? { cursor } : {},
        ...size !== void 0 ? { size } : {},
        ...archiveState !== void 0 ? { archiveState } : {},
        ...view !== void 0 ? { view } : {},
        ...group !== void 0 ? { group } : {},
        ...parentSessionId !== void 0 ? { parentSessionId } : {},
        ...parsedSource
      };
      const usePersisted = readOnlySecondary || runtime.primary || view === "organized" || archiveState === "archived" || parentSessionId !== void 0 || parsedSource.sourceType !== void 0 || (cursor !== void 0 && cursor !== "" ? isNumericSessionCursor(cursor) : await hasActivePersistedSessions(key));
      if (!usePersisted && (view !== void 0 || archiveState === "archived" || parentSessionId !== void 0 || parsedSource.sourceType !== void 0)) {
        throw new Error(
          "session list live path received persisted-only options"
        );
      }
      const result = usePersisted ? await runWorkspaceInspectionWithLogPolicy(
        runtime,
        () => listWorkspaceSessionsForResponse(runtime.bridge, key, options, {
          mergeLive: !readOnlySecondary
        })
      ) : listLiveWorkspaceSessionsForResponse(runtime.bridge, key, options);
      res.status(200).json({
        sessions: result.sessions,
        ...result.nextCursor != null ? { nextCursor: result.nextCursor } : {},
        ...result.liveMergeFailed ? { liveMergeFailed: true } : {},
        ...result.truncated ? { truncated: true } : {}
      });
    } catch (err) {
      if (err instanceof InvalidCursorError) {
        res.status(400).json({
          error: err.message,
          code: "invalid_cursor"
        });
        return;
      }
      if (sendSessionOrganizationError(res, err)) return;
      writeStderrLine(
        `qwen serve: failed to list sessions for workspace ${safeLogValue(
          key
        )} (options=${safeLogValue(
          JSON.stringify({
            view: req.query["view"],
            archiveState: req.query["archiveState"],
            group: req.query["group"]
          })
        )}): ${safeLogValue(
          err instanceof Error ? err.message : String(err)
        )}`
      );
      res.status(500).json({
        error: "Failed to list sessions",
        code: "session_list_failed"
      });
    }
  }, "listWorkspaceSessionsHandler");
  app.get("/workspace/:id/sessions", listWorkspaceSessionsHandler("id"));
  app.get(
    "/workspaces/:workspace/sessions",
    listWorkspaceSessionsHandler("workspace")
  );
  app.post(
    "/session/:id/model",
    mutate(),
    withOwnerMutableSession(
      "POST /session/:id/model",
      async (req, res, sessionId, runtime) => {
        const body = safeBody(req);
        const modelId = body["modelId"];
        if (typeof modelId !== "string" || !modelId) {
          res.status(400).json({
            error: "`modelId` is required and must be a non-empty string"
          });
          return;
        }
        const clientId = parseClientIdHeader(req, res);
        if (clientId === null) return;
        const response = await runtime.bridge.setSessionModel(
          sessionId,
          {
            ...body,
            sessionId,
            modelId
          },
          clientId !== void 0 ? { clientId } : void 0
        );
        res.status(200).json(response);
      }
    )
  );
  app.post(
    "/session/:id/recap",
    mutate(),
    withOwnerMutableSession(
      "POST /session/:id/recap",
      async (req, res, sessionId, runtime) => {
        const clientId = parseClientIdHeader(req, res);
        if (clientId === null) return;
        const response = await runtime.bridge.generateSessionRecap(
          sessionId,
          clientId !== void 0 ? { clientId } : void 0
        );
        if (daemonLog) {
          const recap = response.recap;
          daemonLog.info(
            recap ? `recap generated len=${recap.length}` : "recap returned null",
            { sessionId, clientId }
          );
        }
        res.status(200).json(response);
      }
    )
  );
  app.post(
    "/session/:id/btw",
    mutate(),
    withOwnerMutableSession(
      "POST /session/:id/btw",
      async (req, res, sessionId, runtime) => {
        const body = safeBody(req);
        const question = body["question"];
        if (typeof question !== "string" || question.trim().length === 0 || question.length > BTW_MAX_INPUT_LENGTH) {
          res.status(400).json({
            error: `\`question\` is required, must be a non-empty string, and at most ${BTW_MAX_INPUT_LENGTH} characters`
          });
          return;
        }
        const abort = new AbortController();
        const onResClose = /* @__PURE__ */ __name(() => {
          if (!res.writableEnded) abort.abort();
        }, "onResClose");
        res.once("close", onResClose);
        const clientId = parseClientIdHeader(req, res);
        if (clientId === null) {
          res.off("close", onResClose);
          return;
        }
        try {
          const result = await runtime.bridge.generateSessionBtw(
            sessionId,
            question.trim(),
            abort.signal,
            clientId !== void 0 ? { clientId } : void 0
          );
          res.status(200).json(result);
        } catch (err) {
          if (err instanceof DOMException && err.name === "AbortError" && abort.signal.aborted) {
            return;
          }
          sendBridgeError2(res, err, {
            route: "POST /session/:id/btw",
            sessionId
          });
        } finally {
          res.off("close", onResClose);
        }
      }
    )
  );
  const MID_TURN_MESSAGE_MAX_LENGTH = 16 * 1024;
  app.post(
    "/session/:id/mid-turn-message",
    mutate(),
    withOwnerMutableSession(
      "POST /session/:id/mid-turn-message",
      (req, res, sessionId, runtime) => {
        const body = safeBody(req);
        const message = body["message"];
        const trimmed = typeof message === "string" ? message.trim() : "";
        if (trimmed.length === 0) {
          res.status(400).json({
            error: "`message` is required and must be a non-empty string"
          });
          return;
        }
        if (trimmed.length > MID_TURN_MESSAGE_MAX_LENGTH) {
          res.status(400).json({
            error: `\`message\` must be at most ${MID_TURN_MESSAGE_MAX_LENGTH} characters`
          });
          return;
        }
        const clientId = parseClientIdHeader(req, res);
        if (clientId === null) return;
        const result = runtime.bridge.enqueueMidTurnMessage(
          sessionId,
          trimmed,
          clientId !== void 0 ? { clientId } : void 0
        );
        res.status(200).json(result);
      }
    )
  );
  app.get("/session/:id/pending-prompts", (req, res) => {
    const sessionId = requireSessionId(req, res);
    if (sessionId === null) return;
    const runtime = resolveLiveSessionRuntime(
      sessionId,
      res,
      "GET /session/:id/pending-prompts"
    );
    if (!runtime) return;
    const clientId = parseClientIdHeader(req, res);
    if (clientId === null) return;
    try {
      const pendingPrompts = runtime.bridge.getPendingPrompts(
        sessionId,
        clientId !== void 0 ? { clientId } : void 0
      );
      res.status(200).json({ pendingPrompts });
    } catch (err) {
      sendBridgeError2(res, err, {
        route: "GET /session/:id/pending-prompts",
        sessionId
      });
    }
  });
  app.delete(
    "/session/:id/pending-prompts/:promptId",
    mutate(),
    withOwnerMutableSession(
      "DELETE /session/:id/pending-prompts/:promptId",
      (req, res, sessionId, runtime) => {
        const clientId = parseClientIdHeader(req, res);
        if (clientId === null) return;
        const promptId = req.params["promptId"];
        if (!promptId) {
          res.status(400).json({ error: "`promptId` route parameter is required" });
          return;
        }
        const result = runtime.bridge.removePendingPrompt(
          sessionId,
          promptId,
          clientId !== void 0 ? { clientId } : void 0
        );
        res.status(200).json(result);
      }
    )
  );
  app.post(
    "/session/:id/shell",
    mutate({ strict: true }),
    withOwnerMutableSession(
      "POST /session/:id/shell",
      async (req, res, sessionId, runtime) => {
        if (!sessionShellCommandEnabled) {
          sendBridgeError2(res, new SessionShellDisabledError(), {
            route: "POST /session/:id/shell",
            sessionId
          });
          return;
        }
        const clientId = parseClientIdHeader(req, res);
        if (clientId === null) {
          return;
        }
        if (clientId === void 0) {
          sendBridgeError2(res, new SessionShellClientRequiredError(), {
            route: "POST /session/:id/shell",
            sessionId
          });
          return;
        }
        const body = safeBody(req);
        const command = body["command"];
        if (typeof command !== "string" || command.trim().length === 0) {
          res.status(400).json({
            error: "`command` is required and must be a non-empty string"
          });
          return;
        }
        const abort = new AbortController();
        const onResClose = /* @__PURE__ */ __name(() => {
          if (!res.writableEnded) abort.abort();
        }, "onResClose");
        res.once("close", onResClose);
        try {
          const result = await runtime.bridge.executeShellCommand(
            sessionId,
            command.trim(),
            abort.signal,
            { clientId }
          );
          if (daemonLog) {
            daemonLog.info("shell command completed", {
              sessionId,
              clientId,
              exitCode: result.exitCode,
              workspaceId: runtime.workspaceId,
              workspaceCwd: runtime.workspaceCwd
            });
          }
          res.status(200).json(result);
        } catch (err) {
          if (err instanceof DOMException && err.name === "AbortError" && abort.signal.aborted) {
            return;
          }
          sendBridgeError2(res, err, {
            route: "POST /session/:id/shell",
            sessionId
          });
        } finally {
          res.off("close", onResClose);
        }
      }
    )
  );
  app.get(
    "/session/:id/rewind/snapshots",
    withOwnerReadSession(
      "GET /session/:id/rewind/snapshots",
      async (_req, res, sessionId, runtime) => {
        const response = await runtime.bridge.getRewindSnapshots(sessionId);
        if (daemonLog) {
          daemonLog.info("rewind snapshots loaded", {
            sessionId,
            snapshotCount: response.snapshots.length,
            workspaceId: runtime.workspaceId,
            workspaceCwd: runtime.workspaceCwd
          });
        }
        res.status(200).json(response);
      }
    )
  );
  app.post(
    "/session/:id/rewind",
    mutate({ strict: true }),
    withOwnerMutableSession(
      "POST /session/:id/rewind",
      async (req, res, sessionId, runtime) => {
        const body = safeBody(req);
        const promptId = body["promptId"];
        if (typeof promptId !== "string" || promptId.length === 0) {
          res.status(400).json({
            error: "`promptId` is required and must be a non-empty string",
            code: "missing_prompt_id"
          });
          return;
        }
        const rewindFiles = body["rewindFiles"];
        if (rewindFiles !== void 0 && typeof rewindFiles !== "boolean") {
          res.status(400).json({
            error: "`rewindFiles` must be a boolean when provided",
            code: "invalid_rewind_files_flag"
          });
          return;
        }
        const clientId = parseClientIdHeader(req, res);
        if (clientId === null) return;
        const response = await runtime.bridge.rewindSession(
          sessionId,
          { promptId, rewindFiles: rewindFiles !== false },
          clientId !== void 0 ? { clientId } : void 0
        );
        if (daemonLog) {
          daemonLog.info("session rewind completed", {
            sessionId,
            promptId,
            rewindFiles: rewindFiles !== false,
            rewound: response.rewound,
            filesChangedCount: response.filesChanged.length,
            filesFailedCount: response.filesFailed.length,
            workspaceId: runtime.workspaceId,
            workspaceCwd: runtime.workspaceCwd
          });
        }
        res.status(200).json(response);
      }
    )
  );
  app.post(
    "/session/:id/approval-mode",
    mutate(),
    withOwnerMutableSession(
      "POST /session/:id/approval-mode",
      async (req, res, sessionId, runtime) => {
        const body = safeBody(req);
        const mode = body["mode"];
        const persist = body["persist"];
        if (typeof mode !== "string" || !APPROVAL_MODES.includes(mode)) {
          res.status(400).json({
            error: "`mode` is required and must be one of the allowed values",
            code: "invalid_approval_mode",
            allowed: APPROVAL_MODES
          });
          return;
        }
        if (persist !== void 0 && typeof persist !== "boolean") {
          res.status(400).json({
            error: "`persist` must be a boolean when provided",
            code: "invalid_persist_flag"
          });
          return;
        }
        const clientId = parseClientIdHeader(req, res);
        if (clientId === null) return;
        const response = await runtime.bridge.setSessionApprovalMode(
          sessionId,
          mode,
          { persist: persist === true },
          clientId !== void 0 ? { clientId } : void 0
        );
        res.status(200).json(response);
      }
    )
  );
  app.post(
    "/session/:id/language",
    mutate(),
    withOwnerMutableSession(
      "POST /session/:id/language",
      async (req, res, sessionId, runtime) => {
        const body = safeBody(req);
        const language = body["language"];
        const syncOutputLanguage = body["syncOutputLanguage"];
        if (typeof language !== "string" || !LANGUAGE_CODES.includes(language)) {
          res.status(400).json({
            error: "`language` is required and must be one of: " + LANGUAGE_CODES.join(", "),
            code: "invalid_language",
            allowed: LANGUAGE_CODES
          });
          return;
        }
        if (syncOutputLanguage !== void 0 && typeof syncOutputLanguage !== "boolean") {
          res.status(400).json({
            error: "`syncOutputLanguage` must be a boolean when provided",
            code: "invalid_sync_flag"
          });
          return;
        }
        const clientId = parseClientIdHeader(req, res);
        if (clientId === null) return;
        const response = await runtime.bridge.setSessionLanguage(
          sessionId,
          {
            language,
            syncOutputLanguage: syncOutputLanguage === true
          },
          clientId !== void 0 ? { clientId } : void 0
        );
        res.status(200).json(response);
      }
    )
  );
}
__name(registerSessionRoutes, "registerSessionRoutes");

// packages/cli/src/serve/routes/scheduled-tasks.ts
init_esbuild_shims();
var MAX_SCHEDULED_TASKS = MAX_JOBS;
var MAX_PROMPT_LENGTH = 1e5;
var MAX_NAME_LENGTH2 = 200;
var MAX_CRON_LENGTH = 200;
var MAX_SESSION_NAME_LENGTH = 60;
function scheduledTaskSessionName(label) {
  const cleaned = stripTerminalControlSequences(label).replace(/[\u061c\u200e\u200f\u202a-\u202e\u2066-\u2069]/g, "").trim().replace(/\s+/g, " ");
  let short = cleaned;
  if (cleaned.length > MAX_SESSION_NAME_LENGTH) {
    let cut = MAX_SESSION_NAME_LENGTH - 1;
    const boundary = cleaned.charCodeAt(cut - 1);
    if (boundary >= 55296 && boundary <= 56319) cut -= 1;
    short = `${cleaned.slice(0, cut)}\u2026`;
  }
  return `\u23F0 ${short}`;
}
__name(scheduledTaskSessionName, "scheduledTaskSessionName");
function computeNextRunAt(task) {
  if (task.enabled === false) return null;
  return nextDurableFireMs(task);
}
__name(computeNextRunAt, "computeNextRunAt");
function toView(task) {
  return {
    id: task.id,
    name: typeof task.name === "string" && task.name.length > 0 ? task.name : null,
    cron: task.cron,
    prompt: task.prompt,
    recurring: task.recurring,
    // Absent enabled defaults to enabled — tool-created tasks never write it.
    // A legacy guarded task (isolated run mode + precondition, both removed) is
    // reported as NOT runnable — `enabled: false` with no `nextRunAt` — so the
    // management UI never shows it as active or offers a Run affordance for a
    // task the scheduler refuses to fire. Fail closed on the read path too, not
    // just the tick. `POST /:id/run` rejects it as a second guard.
    enabled: task.enabled !== false && !taskHasLegacyCondition(task),
    createdAt: task.createdAt,
    lastFiredAt: task.lastFiredAt,
    nextRunAt: taskHasLegacyCondition(task) ? null : computeNextRunAt(task),
    // The task's bound session (its run-history transcript), or null for an
    // unbound tool-created/legacy task.
    sessionId: typeof task.sessionId === "string" && task.sessionId.length > 0 ? task.sessionId : null,
    // Absent runs (tool-created / never-fired) normalizes to [] so the client
    // never special-cases undefined.
    runs: Array.isArray(task.runs) ? task.runs : []
  };
}
__name(toView, "toView");
function validateCron(cron) {
  try {
    parseCron(cron);
    nextFireTime(cron, /* @__PURE__ */ new Date());
    return null;
  } catch (err) {
    return err instanceof Error ? err.message : String(err);
  }
}
__name(validateCron, "validateCron");
function canonicalCron(cron) {
  try {
    const f = parseCron(cron);
    const s = /* @__PURE__ */ __name((set) => [...set].sort((a, b) => a - b).join(","), "s");
    return [
      s(f.minute),
      s(f.hour),
      s(f.dayOfMonth),
      s(f.month),
      s(f.dayOfWeek),
      f.domIsWild ? "W" : "",
      f.dowIsWild ? "W" : ""
    ].join("|");
  } catch {
    return null;
  }
}
__name(canonicalCron, "canonicalCron");
function registerScheduledTaskCrudRoutes(app, deps) {
  const { prefix, resolveTarget, mutate, safeBody: safeBody2 } = deps;
  const base = `${prefix}/scheduled-tasks`;
  app.get(base, async (req, res) => {
    const target = resolveTarget(req, res);
    if (!target) return;
    try {
      const tasks = await readCronTasks(target.workspaceCwd);
      res.status(200).json({ v: 1, tasks: tasks.map(toView) });
    } catch (err) {
      writeStderrLine(
        `qwen serve: GET ${base} failed: ${err instanceof Error ? err.message : String(err)}`
      );
      res.status(500).json({
        error: "Failed to read scheduled tasks (the tasks file may be corrupt)",
        code: "scheduled_tasks_read_failed"
      });
    }
  });
  app.post(base, mutate(), async (req, res) => {
    const target = resolveTarget(req, res);
    if (!target) return;
    const { workspaceCwd, bridge } = target;
    const body = safeBody2(req);
    const cron = typeof body["cron"] === "string" ? body["cron"].trim() : "";
    if (cron.length === 0) {
      res.status(400).json({
        error: "`cron` is required and must be a non-empty string",
        code: "invalid_cron"
      });
      return;
    }
    if (cron.length > MAX_CRON_LENGTH) {
      res.status(400).json({
        error: `\`cron\` exceeds ${MAX_CRON_LENGTH}-character limit`,
        code: "invalid_cron"
      });
      return;
    }
    const cronError = validateCron(cron);
    if (cronError) {
      res.status(400).json({ error: cronError, code: "invalid_cron" });
      return;
    }
    const prompt = typeof body["prompt"] === "string" ? body["prompt"].trim() : "";
    if (prompt.length === 0) {
      res.status(400).json({
        error: "`prompt` is required and must be a non-empty string",
        code: "invalid_prompt"
      });
      return;
    }
    if (prompt.length > MAX_PROMPT_LENGTH) {
      res.status(400).json({
        error: `\`prompt\` exceeds ${MAX_PROMPT_LENGTH}-character limit`,
        code: "invalid_prompt"
      });
      return;
    }
    const nameResult = parseNameField(body["name"]);
    if (nameResult.error) {
      res.status(400).json({ error: nameResult.error, code: "invalid_name" });
      return;
    }
    if (body["recurring"] !== void 0 && typeof body["recurring"] !== "boolean") {
      res.status(400).json({
        error: "`recurring` must be a boolean",
        code: "invalid_recurring"
      });
      return;
    }
    if (body["enabled"] !== void 0 && typeof body["enabled"] !== "boolean") {
      res.status(400).json({
        error: "`enabled` must be a boolean",
        code: "invalid_enabled"
      });
      return;
    }
    const removedField = findRemovedTaskField(body);
    if (removedField) {
      res.status(400).json(removedFieldError(removedField));
      return;
    }
    const recurring = body["recurring"] !== false;
    const enabled = body["enabled"] !== false;
    const taskId = generateCronTaskId();
    let boundSessionId;
    if (bridge) {
      try {
        if ((await readCronTasks(workspaceCwd)).length >= MAX_SCHEDULED_TASKS) {
          res.status(409).json({
            error: `Maximum number of scheduled tasks (${MAX_SCHEDULED_TASKS}) reached`,
            code: "max_tasks_reached"
          });
          return;
        }
      } catch {
      }
      try {
        const session = await bridge.spawnOrAttach({
          workspaceCwd,
          sessionScope: "thread",
          sourceType: "scheduled_task",
          sourceId: taskId
        });
        boundSessionId = session.sessionId;
        try {
          bridge.updateSessionMetadata(boundSessionId, {
            displayName: scheduledTaskSessionName(nameResult.value ?? prompt)
          });
        } catch {
        }
      } catch (err) {
        writeStderrLine(
          `qwen serve: POST ${base} failed to create the task's session: ${err instanceof Error ? err.message : String(err)}`
        );
        res.status(500).json({
          error: "Failed to create the task's session",
          code: "scheduled_tasks_session_failed"
        });
        return;
      }
    }
    const now = Date.now();
    const task = {
      id: taskId,
      cron,
      prompt,
      recurring,
      createdAt: now,
      // Pin to the creation minute so the scheduler can't fire during the
      // minute the task was created — same guard cronScheduler.create uses.
      lastFiredAt: now - now % 6e4,
      enabled,
      ...boundSessionId !== void 0 ? { sessionId: boundSessionId } : {},
      ...nameResult.value !== void 0 ? { name: nameResult.value } : {}
    };
    const rollbackSession = /* @__PURE__ */ __name(async () => {
      if (boundSessionId !== void 0 && bridge) {
        await bridge.closeSession(boundSessionId).catch(() => {
        });
        await new SessionService(workspaceCwd).removeSession(boundSessionId).catch(() => {
        });
      }
    }, "rollbackSession");
    let overCap = false;
    try {
      await updateCronTasks(workspaceCwd, (tasks) => {
        if (tasks.length >= MAX_SCHEDULED_TASKS) {
          overCap = true;
          return tasks;
        }
        return [...tasks, task];
      });
    } catch (err) {
      await rollbackSession();
      writeStderrLine(
        `qwen serve: POST ${base} failed: ${err instanceof Error ? err.message : String(err)}`
      );
      res.status(500).json({
        error: "Failed to create scheduled task",
        code: "scheduled_tasks_write_failed"
      });
      return;
    }
    if (overCap) {
      await rollbackSession();
      res.status(409).json({
        error: `Maximum number of scheduled tasks (${MAX_SCHEDULED_TASKS}) reached`,
        code: "max_tasks_reached"
      });
      return;
    }
    res.status(201).json(toView(task));
  });
  app.patch(`${base}/:id`, mutate(), async (req, res) => {
    const target = resolveTarget(req, res);
    if (!target) return;
    const { workspaceCwd, bridge } = target;
    const id = typeof req.params["id"] === "string" ? req.params["id"] : "";
    if (id.length === 0) {
      res.status(400).json({ error: "Task id is required", code: "invalid_id" });
      return;
    }
    const body = safeBody2(req);
    const patch = {};
    let clearName = false;
    const removedPatchField = findRemovedTaskField(body);
    if (removedPatchField) {
      res.status(400).json(removedFieldError(removedPatchField));
      return;
    }
    if ("cron" in body) {
      const cron = typeof body["cron"] === "string" ? body["cron"].trim() : "";
      if (cron.length === 0 || cron.length > MAX_CRON_LENGTH) {
        res.status(400).json({
          error: "`cron` must be a non-empty string within the length limit",
          code: "invalid_cron"
        });
        return;
      }
      const cronError = validateCron(cron);
      if (cronError) {
        res.status(400).json({ error: cronError, code: "invalid_cron" });
        return;
      }
      patch.cron = cron;
    }
    if ("prompt" in body) {
      const prompt = typeof body["prompt"] === "string" ? body["prompt"].trim() : "";
      if (prompt.length === 0 || prompt.length > MAX_PROMPT_LENGTH) {
        res.status(400).json({
          error: "`prompt` must be a non-empty string within the length limit",
          code: "invalid_prompt"
        });
        return;
      }
      patch.prompt = prompt;
    }
    if ("name" in body) {
      const nameResult = parseNameField(body["name"]);
      if (nameResult.error) {
        res.status(400).json({ error: nameResult.error, code: "invalid_name" });
        return;
      }
      if (nameResult.value === void 0) {
        clearName = true;
      } else {
        patch.name = nameResult.value;
      }
    }
    if ("recurring" in body) {
      if (typeof body["recurring"] !== "boolean") {
        res.status(400).json({
          error: "`recurring` must be a boolean",
          code: "invalid_recurring"
        });
        return;
      }
      patch.recurring = body["recurring"];
    }
    if ("enabled" in body) {
      if (typeof body["enabled"] !== "boolean") {
        res.status(400).json({
          error: "`enabled` must be a boolean",
          code: "invalid_enabled"
        });
        return;
      }
      patch.enabled = body["enabled"];
    }
    if (Object.keys(patch).length === 0 && !clearName) {
      res.status(400).json({
        error: "No updatable fields provided",
        code: "empty_patch"
      });
      return;
    }
    let found = false;
    let updated;
    let blockedByArchive = false;
    let blockedLegacy = false;
    try {
      await updateCronTasks(workspaceCwd, (tasks) => {
        const idx = tasks.findIndex((t) => t.id === id);
        if (idx === -1) return tasks;
        found = true;
        const current = tasks[idx];
        if (patch.enabled === true && taskHasLegacyCondition(current)) {
          blockedLegacy = true;
          return tasks;
        }
        if (patch.enabled === true && current.disabledByArchive === true) {
          blockedByArchive = true;
          return tasks;
        }
        const next = { ...current, ...patch };
        if (clearName) delete next.name;
        const justReEnabled = current.enabled === false && patch.enabled === true;
        const cronChanged = patch.cron !== void 0 && canonicalCron(patch.cron) !== canonicalCron(current.cron);
        const becameRecurring = patch.recurring === true && current.recurring !== true;
        const becameOneShot = patch.recurring === false && current.recurring !== false;
        {
          const now = Date.now();
          const minute = now - now % 6e4;
          if (next.recurring && (justReEnabled || cronChanged || becameRecurring)) {
            next.lastFiredAt = minute;
          } else if (!next.recurring && (justReEnabled || cronChanged || becameOneShot)) {
            next.createdAt = now;
            next.lastFiredAt = minute;
          }
        }
        updated = next;
        return tasks.map((t, i) => i === idx ? next : t);
      });
    } catch (err) {
      writeStderrLine(
        `qwen serve: PATCH ${base}/${id} failed: ${err instanceof Error ? err.message : String(err)}`
      );
      res.status(500).json({
        error: "Failed to update scheduled task",
        code: "scheduled_tasks_write_failed"
      });
      return;
    }
    if (blockedLegacy) {
      res.status(409).json({
        error: "This task uses the removed isolated run mode with a precondition and can no longer be enabled or run. Recreate it (and call the `create_sub_session` tool from the prompt if you need per-run isolation).",
        code: "task_legacy_unsupported"
      });
      return;
    }
    if (blockedByArchive) {
      res.status(409).json({
        error: "This task was disabled by archiving its session; unarchive the session to re-enable it.",
        code: "task_session_archived"
      });
      return;
    }
    if (!found || !updated) {
      res.status(404).json({ error: "Task not found", code: "task_not_found" });
      return;
    }
    const effectiveLabelChanged = patch.name !== void 0 || clearName || patch.prompt !== void 0 && updated.name === void 0;
    if (bridge && updated.sessionId && effectiveLabelChanged) {
      try {
        bridge.updateSessionMetadata(updated.sessionId, {
          displayName: scheduledTaskSessionName(updated.name ?? updated.prompt)
        });
      } catch {
      }
    }
    res.status(200).json(toView(updated));
  });
  app.delete(`${base}/:id`, mutate(), async (req, res) => {
    const target = resolveTarget(req, res);
    if (!target) return;
    const { workspaceCwd, bridge } = target;
    const id = typeof req.params["id"] === "string" ? req.params["id"] : "";
    if (id.length === 0) {
      res.status(400).json({ error: "Task id is required", code: "invalid_id" });
      return;
    }
    let boundSessionId;
    let removed = false;
    try {
      await updateCronTasks(workspaceCwd, (tasks) => {
        const idx = tasks.findIndex((t) => t.id === id);
        if (idx === -1) return tasks;
        const match = tasks[idx].sessionId;
        if (typeof match === "string" && match.length > 0) {
          boundSessionId = match;
        }
        removed = true;
        return tasks.filter((_, i) => i !== idx);
      });
    } catch (err) {
      writeStderrLine(
        `qwen serve: DELETE ${base}/${id} failed: ${err instanceof Error ? err.message : String(err)}`
      );
      res.status(500).json({
        error: "Failed to delete scheduled task",
        code: "scheduled_tasks_write_failed"
      });
      return;
    }
    if (!removed) {
      res.status(404).json({ error: "Task not found", code: "task_not_found" });
      return;
    }
    if (boundSessionId && bridge) {
      await bridge.closeSession(boundSessionId).catch(() => {
      });
    }
    res.status(200).json({ deleted: true, id });
  });
  app.post(`${base}/:id/run`, mutate(), async (req, res) => {
    const target = resolveTarget(req, res);
    if (!target) return;
    const { workspaceCwd } = target;
    const id = typeof req.params["id"] === "string" ? req.params["id"] : "";
    if (id.length === 0) {
      res.status(400).json({ error: "Task id is required", code: "invalid_id" });
      return;
    }
    const now = Date.now();
    let found = false;
    let blockedDisabled = false;
    let blockedLegacy = false;
    let updated;
    try {
      await updateCronTasks(workspaceCwd, (tasks) => {
        const idx = tasks.findIndex((t) => t.id === id);
        if (idx === -1) return tasks;
        found = true;
        const current = tasks[idx];
        if (taskHasLegacyCondition(current)) {
          blockedLegacy = true;
          return tasks;
        }
        if (current.enabled === false) {
          blockedDisabled = true;
          return tasks;
        }
        const next = {
          ...current,
          lastFiredAt: now,
          runs: appendCronRun(current.runs, {
            at: now,
            kind: "manual",
            ...current.sessionId ? { sessionId: current.sessionId } : {}
          })
        };
        updated = next;
        if (!current.recurring) {
          return tasks.filter((_, i) => i !== idx);
        }
        return tasks.map((t, i) => i === idx ? next : t);
      });
    } catch (err) {
      writeStderrLine(
        `qwen serve: POST ${base}/${id}/run failed: ${err instanceof Error ? err.message : String(err)}`
      );
      res.status(500).json({
        error: "Failed to record scheduled task run",
        code: "scheduled_tasks_write_failed"
      });
      return;
    }
    if (blockedLegacy) {
      res.status(409).json({
        error: "This task uses the removed isolated run mode with a precondition and can no longer run. Recreate it (and call the `create_sub_session` tool from the prompt if you need per-run isolation).",
        code: "task_legacy_unsupported"
      });
      return;
    }
    if (blockedDisabled) {
      res.status(409).json({
        error: "Cannot run a disabled task; enable it first (unarchive its session if it was archived).",
        code: "task_disabled"
      });
      return;
    }
    if (!found || !updated) {
      res.status(404).json({ error: "Task not found", code: "task_not_found" });
      return;
    }
    const view = toView(updated);
    if (!updated.recurring) view.nextRunAt = null;
    res.status(200).json(view);
  });
}
__name(registerScheduledTaskCrudRoutes, "registerScheduledTaskCrudRoutes");
function registerScheduledTasksRoutes(app, deps) {
  const { boundWorkspace, mutate, safeBody: safeBody2, bridge } = deps;
  registerScheduledTaskCrudRoutes(app, {
    prefix: "",
    resolveTarget: /* @__PURE__ */ __name(() => ({ workspaceCwd: boundWorkspace, bridge }), "resolveTarget"),
    mutate,
    safeBody: safeBody2
  });
}
__name(registerScheduledTasksRoutes, "registerScheduledTasksRoutes");
function registerWorkspaceQualifiedScheduledTasksRoutes(app, deps) {
  const { workspaceRegistry, mutate, safeBody: safeBody2, manageScheduledTaskSessions } = deps;
  registerScheduledTaskCrudRoutes(app, {
    prefix: "/workspaces/:workspace",
    resolveTarget: /* @__PURE__ */ __name((req, res) => {
      const runtime = resolveWorkspaceRuntimeFromParam(
        workspaceRegistry,
        req,
        res
      );
      if (!runtime) return null;
      if (!requireTrustedWorkspaceRuntime(runtime, res)) return null;
      return {
        workspaceCwd: runtime.workspaceCwd,
        // Mirror the primary surface: only bind a session when management is on,
        // so a bound task always has something to keep it resident + rehydrate it.
        bridge: manageScheduledTaskSessions ? runtime.bridge : void 0
      };
    }, "resolveTarget"),
    mutate,
    safeBody: safeBody2
  });
}
__name(registerWorkspaceQualifiedScheduledTasksRoutes, "registerWorkspaceQualifiedScheduledTasksRoutes");
var REMOVED_TASK_FIELDS = ["runMode", "condition"];
function findRemovedTaskField(body) {
  return REMOVED_TASK_FIELDS.find((field) => field in body);
}
__name(findRemovedTaskField, "findRemovedTaskField");
function removedFieldError(field) {
  return {
    error: `\`${field}\` is no longer supported: the isolated scheduled-task run mode was removed. Every task now runs in its bound session; call the \`create_sub_session\` tool from the task prompt for per-run isolation.`,
    code: "unsupported_field"
  };
}
__name(removedFieldError, "removedFieldError");
function parseNameField(raw) {
  if (raw === void 0 || raw === null) return { value: void 0 };
  if (typeof raw !== "string") {
    return { error: "`name` must be a string" };
  }
  const trimmed = raw.trim();
  if (trimmed.length === 0) return { value: void 0 };
  if (trimmed.length > MAX_NAME_LENGTH2) {
    return { error: `\`name\` exceeds ${MAX_NAME_LENGTH2}-character limit` };
  }
  return { value: trimmed };
}
__name(parseNameField, "parseNameField");

// packages/cli/src/serve/routes/usage-stats.ts
init_esbuild_shims();
var DEFAULT_HEATMAP_DAYS = 183;
var MIN_HEATMAP_DAYS = 1;
var MAX_HEATMAP_DAYS = 366;
var DEFAULT_CACHE_TTL_MS = 6e4;
var USAGE_RANGES = ["today", "week", "month"];
function parseRange(raw) {
  return typeof raw === "string" && USAGE_RANGES.includes(raw) ? raw : "today";
}
__name(parseRange, "parseRange");
function parseHeatmapDays(raw) {
  const value = typeof raw === "string" ? Number.parseInt(raw, 10) : Number.NaN;
  if (!Number.isFinite(value)) return DEFAULT_HEATMAP_DAYS;
  return Math.min(MAX_HEATMAP_DAYS, Math.max(MIN_HEATMAP_DAYS, value));
}
__name(parseHeatmapDays, "parseHeatmapDays");
function registerUsageStatsRoutes(app, deps = {}) {
  const loadHistory = deps.loadHistory ?? (() => loadUsageHistoryWithLive());
  const ttlMs = deps.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS;
  let cache = null;
  const getRecords = /* @__PURE__ */ __name(() => {
    const now = Date.now();
    const fresh = cache !== null && (cache.settledAt === null || now - cache.settledAt < ttlMs);
    if (!fresh) {
      const entry = { promise: loadHistory(), settledAt: null };
      cache = entry;
      entry.promise.then(
        () => {
          if (cache === entry) entry.settledAt = Date.now();
        },
        () => {
          if (cache === entry) cache = null;
        }
      );
    }
    return cache.promise;
  }, "getRecords");
  app.get("/usage/dashboard", async (req, res) => {
    const range = parseRange(req.query["range"]);
    const heatmapDays = parseHeatmapDays(req.query["heatmapDays"]);
    try {
      const records = await getRecords();
      const dashboard = buildUsageDashboard(records, { range, heatmapDays });
      res.status(200).json(dashboard);
    } catch (err) {
      writeStderrLine(
        `qwen serve: GET /usage/dashboard failed: ${err instanceof Error ? err.message : String(err)}`
      );
      res.status(500).json({
        error: "Failed to load usage dashboard",
        code: "usage_dashboard_failed"
      });
    }
  });
}
__name(registerUsageStatsRoutes, "registerUsageStatsRoutes");

// packages/cli/src/serve/scheduled-task-keepalive.ts
init_esbuild_shims();
import * as fsSync from "node:fs";
import * as path12 from "node:path";
var log = createDebugLogger("SCHED_KEEPALIVE");
function collectBoundSessionIds(tasks) {
  const seen = /* @__PURE__ */ new Set();
  const ids = [];
  for (const task of tasks) {
    const sessionId = task.sessionId;
    if (task.enabled === false || // disabled (e.g. archived) — let it be reaped
    taskHasLegacyCondition(task) || // legacy guarded — can never fire, don't pin
    typeof sessionId !== "string" || sessionId.length === 0 || seen.has(sessionId)) {
      continue;
    }
    seen.add(sessionId);
    ids.push(sessionId);
  }
  return ids;
}
__name(collectBoundSessionIds, "collectBoundSessionIds");
var KEEPALIVE_REVIVE_TIMEOUT_MS = 3e4;
var KEEPALIVE_SPAWN_TIMEOUT_MS = 3e4;
var MAX_REVIVE_BACKOFF_MS = 30 * 6e4;
async function bindAndNameSessions(bridge, boundWorkspace, tasks, renamed, spawnTimeoutMs, binding) {
  const unbound = tasks.filter(
    (t) => !t.sessionId && t.enabled !== false && !taskHasLegacyCondition(t) && !binding.has(t.id)
  );
  const needsName = tasks.filter(
    (t) => t.sessionId && t.enabled !== false && !taskHasLegacyCondition(t) && !renamed.has(t.sessionId)
  );
  for (const task of unbound) {
    let spawnedSessionId;
    try {
      binding.add(task.id);
      const rawSpawn = bridge.spawnOrAttach({
        workspaceCwd: boundWorkspace,
        sessionScope: "thread",
        sourceType: "scheduled_task",
        sourceId: task.id
      });
      let timedOut = false;
      rawSpawn.then(({ sessionId: sessionId2 }) => {
        if (timedOut) {
          log.debug(
            "keepalive: late spawn resolved, cleaning up",
            task.id,
            sessionId2
          );
          bridge.closeSession(sessionId2).catch(() => {
          });
          new SessionService(boundWorkspace).removeSession(sessionId2).catch(() => {
          });
        }
      }).catch(() => {
      }).finally(() => {
        binding.delete(task.id);
      });
      const { sessionId } = await withTimeout(
        rawSpawn,
        spawnTimeoutMs,
        `spawnOrAttach(${task.id})`
      ).catch((err) => {
        timedOut = true;
        throw err;
      });
      spawnedSessionId = sessionId;
      try {
        bridge.updateSessionMetadata(sessionId, {
          displayName: scheduledTaskSessionName(task.prompt)
        });
        renamed.add(sessionId);
      } catch {
      }
      let matched = false;
      await updateCronTasks(boundWorkspace, (list) => {
        if (!list.some(
          (t) => t.id === task.id && !t.sessionId && t.enabled !== false
        )) {
          return list;
        }
        const result = list.map(
          (t) => t.id === task.id && !t.sessionId && t.enabled !== false ? { ...t, sessionId } : t
        );
        matched = true;
        return result;
      });
      if (!matched) {
        throw new Error(`task ${task.id} no longer on disk`);
      }
      log.debug(
        "keepalive: bound task",
        task.id,
        "to dedicated session",
        sessionId
      );
    } catch (err) {
      log.debug("keepalive: failed to bind task", task.id, err);
      if (spawnedSessionId !== void 0) {
        await bridge.closeSession(spawnedSessionId).catch(() => {
        });
        await new SessionService(boundWorkspace).removeSession(spawnedSessionId).catch(() => {
        });
      }
    }
  }
  for (const task of needsName) {
    const sessionId = task.sessionId;
    try {
      bridge.updateSessionMetadata(sessionId, {
        displayName: scheduledTaskSessionName(task.prompt)
      });
      renamed.add(sessionId);
    } catch (err) {
      log.debug("keepalive: failed to name session", sessionId, err);
    }
  }
}
__name(bindAndNameSessions, "bindAndNameSessions");
function startScheduledTaskKeepalive(opts) {
  const { bridge, boundWorkspace, intervalMs } = opts;
  const reviveTimeoutMs = opts.reviveTimeoutMs ?? KEEPALIVE_REVIVE_TIMEOUT_MS;
  const spawnTimeoutMs = opts.spawnTimeoutMs ?? KEEPALIVE_SPAWN_TIMEOUT_MS;
  const reviveState = /* @__PURE__ */ new Map();
  const reviving = /* @__PURE__ */ new Set();
  const binding = /* @__PURE__ */ new Set();
  const renamed = /* @__PURE__ */ new Set();
  const tick = /* @__PURE__ */ __name(async () => {
    let tasks;
    try {
      tasks = await readCronTasks(boundWorkspace);
    } catch (err) {
      log.debug("keepalive: readCronTasks failed, skipping this pass", err);
      return;
    }
    for (const sessionId of collectBoundSessionIds(tasks)) {
      try {
        bridge.recordHeartbeat(sessionId);
        reviveState.delete(sessionId);
      } catch (err) {
        const state = reviveState.get(sessionId);
        if (reviving.has(sessionId)) {
          continue;
        }
        if (state && Date.now() < state.nextAttemptAt) {
          continue;
        }
        log.debug("keepalive: recordHeartbeat failed for", sessionId, err);
        reviving.add(sessionId);
        const metadata = await new SessionService(
          boundWorkspace
        ).readCreationMetadata(sessionId);
        const load = bridge.loadSession({
          sessionId,
          workspaceCwd: boundWorkspace,
          historyReplay: "response",
          ...metadata
        });
        void load.catch(() => {
        }).finally(() => {
          reviving.delete(sessionId);
        });
        try {
          await withTimeout(load, reviveTimeoutMs, `loadSession(${sessionId})`);
          log.debug("keepalive: revived non-resident session", sessionId);
          reviveState.delete(sessionId);
        } catch (loadErr) {
          const failures = (state?.failures ?? 0) + 1;
          const backoff = Math.min(
            intervalMs * 2 ** Math.min(failures - 1, 6),
            MAX_REVIVE_BACKOFF_MS
          );
          reviveState.set(sessionId, {
            failures,
            nextAttemptAt: Date.now() + backoff
          });
          log.debug(
            "keepalive: failed to revive session",
            sessionId,
            `(failure ${failures}, next retry in ${backoff}ms)`,
            loadErr
          );
        }
      }
    }
    if (reviveState.size > 0 || renamed.size > 0) {
      const live = new Set(tasks.map((t) => t.sessionId));
      for (const id of reviveState.keys()) {
        if (!live.has(id)) reviveState.delete(id);
      }
      for (const id of renamed) {
        if (!live.has(id)) renamed.delete(id);
      }
    }
    await bindAndNameSessions(
      bridge,
      boundWorkspace,
      tasks,
      renamed,
      spawnTimeoutMs,
      binding
    );
  }, "tick");
  let running = false;
  const timer = setInterval(() => {
    if (running) return;
    running = true;
    void tick().finally(() => {
      running = false;
    });
  }, intervalMs);
  timer.unref?.();
  let bindDebounce;
  const cronFilePath = getCronFilePath(boundWorkspace);
  const cronDir = path12.dirname(cronFilePath);
  const cronFileName = path12.basename(cronFilePath);
  let fileWatcher;
  try {
    fsSync.mkdirSync(cronDir, { recursive: true });
    fileWatcher = fsSync.watch(
      cronDir,
      { persistent: false },
      (_event, filename) => {
        if (filename !== null && filename !== cronFileName) return;
        if (bindDebounce) clearTimeout(bindDebounce);
        bindDebounce = setTimeout(() => {
          if (running) return;
          running = true;
          void tick().finally(() => {
            running = false;
          });
        }, 500);
        bindDebounce.unref?.();
      }
    );
    fileWatcher.on("error", () => {
    });
  } catch {
  }
  let stopped = false;
  return {
    stop: /* @__PURE__ */ __name(() => {
      if (stopped) return;
      stopped = true;
      clearInterval(timer);
      if (bindDebounce) clearTimeout(bindDebounce);
      fileWatcher?.close();
    }, "stop"),
    tick
  };
}
__name(startScheduledTaskKeepalive, "startScheduledTaskKeepalive");
var REHYDRATE_LOAD_TIMEOUT_MS = 3e4;
var REHYDRATE_MAX_CONCURRENCY = 4;
async function rehydrateScheduledTaskSessions(deps) {
  const { bridge, boundWorkspace } = deps;
  const timeoutMs = deps.loadTimeoutMs ?? REHYDRATE_LOAD_TIMEOUT_MS;
  let tasks;
  try {
    tasks = await readCronTasks(boundWorkspace);
  } catch (err) {
    log.debug("rehydrate: readCronTasks failed", err);
    return { loaded: [], failed: [] };
  }
  const sessionIds = collectBoundSessionIds(tasks);
  const loaded = [];
  const failed = [];
  const loadOne = /* @__PURE__ */ __name(async (sessionId) => {
    const metadata = await new SessionService(
      boundWorkspace
    ).readCreationMetadata(sessionId);
    const load = bridge.loadSession({
      sessionId,
      workspaceCwd: boundWorkspace,
      historyReplay: "response",
      ...metadata
    });
    void load.catch(() => {
    });
    try {
      await withTimeout(load, timeoutMs, `loadSession(${sessionId})`);
      loaded.push(sessionId);
    } catch (err) {
      failed.push(sessionId);
      try {
        deps.onError?.(sessionId, err);
      } catch {
      }
    }
  }, "loadOne");
  const queue = sessionIds.slice();
  const worker = /* @__PURE__ */ __name(async () => {
    for (let sessionId = queue.shift(); sessionId !== void 0; sessionId = queue.shift()) {
      await loadOne(sessionId);
    }
  }, "worker");
  await Promise.all(
    Array.from(
      { length: Math.min(REHYDRATE_MAX_CONCURRENCY, queue.length) },
      () => worker()
    )
  );
  return { loaded, failed };
}
__name(rehydrateScheduledTaskSessions, "rehydrateScheduledTaskSessions");
function withTimeout(p, ms, label) {
  return new Promise((resolve5, reject) => {
    const timer = setTimeout(() => {
      reject(new Error(`${label} timed out after ${ms}ms`));
    }, ms);
    if (typeof timer.unref === "function") timer.unref();
    p.then(
      (v) => {
        clearTimeout(timer);
        resolve5(v);
      },
      (e) => {
        clearTimeout(timer);
        reject(e);
      }
    );
  });
}
__name(withTimeout, "withTimeout");

// packages/cli/src/serve/routes/workspace-status.ts
init_esbuild_shims();
var MAX_ACP_PREHEAT_TIMEOUT_MS = 6e4;
function registerWorkspaceStatusRoutes(app, deps) {
  const { boundWorkspace, bridge, workspace, mutate, sendBridgeError: sendBridgeError2 } = deps;
  const buildWorkspaceCtx = createBuildWorkspaceCtx(boundWorkspace);
  app.get("/workspace/mcp", async (_req, res) => {
    try {
      const ctx = buildWorkspaceCtx("GET /workspace/mcp");
      res.status(200).json(await workspace.getWorkspaceMcpStatus(ctx));
    } catch (err) {
      sendBridgeError2(res, err, { route: "GET /workspace/mcp" });
    }
  });
  app.get("/workspace/mcp/:server/tools", async (req, res) => {
    const serverName = req.params["server"];
    if (!serverName || typeof serverName !== "string") {
      res.status(400).json({
        error: "Server name path parameter is required",
        code: "invalid_server_name"
      });
      return;
    }
    if (serverName.length > MAX_SERVER_NAME_LENGTH) {
      res.status(400).json({
        error: `Server name exceeds ${MAX_SERVER_NAME_LENGTH}-character limit`,
        code: "invalid_server_name"
      });
      return;
    }
    try {
      res.status(200).json(await bridge.getWorkspaceMcpToolsStatus(serverName));
    } catch (err) {
      sendBridgeError2(res, err, { route: "GET /workspace/mcp/:server/tools" });
    }
  });
  app.get("/workspace/mcp/:server/resources", async (req, res) => {
    const serverName = req.params["server"];
    if (!serverName || typeof serverName !== "string") {
      res.status(400).json({
        error: "Server name path parameter is required",
        code: "invalid_server_name"
      });
      return;
    }
    if (serverName.length > MAX_SERVER_NAME_LENGTH) {
      res.status(400).json({
        error: `Server name exceeds ${MAX_SERVER_NAME_LENGTH}-character limit`,
        code: "invalid_server_name"
      });
      return;
    }
    try {
      res.status(200).json(await bridge.getWorkspaceMcpResourcesStatus(serverName));
    } catch (err) {
      sendBridgeError2(res, err, {
        route: "GET /workspace/mcp/:server/resources"
      });
    }
  });
  app.get("/workspace/skills", async (_req, res) => {
    try {
      const ctx = buildWorkspaceCtx("GET /workspace/skills");
      res.status(200).json(await workspace.getWorkspaceSkillsStatus(ctx));
    } catch (err) {
      sendBridgeError2(res, err, { route: "GET /workspace/skills" });
    }
  });
  app.post("/workspace/acp/preheat", mutate(), async (req, res) => {
    try {
      const ctx = buildWorkspaceCtx("POST /workspace/acp/preheat");
      const timeoutMsRaw = req.query["timeoutMs"];
      const timeoutMs = typeof timeoutMsRaw === "string" && timeoutMsRaw.trim() ? Number(timeoutMsRaw) : void 0;
      if (timeoutMs !== void 0 && (!Number.isFinite(timeoutMs) || !Number.isInteger(timeoutMs) || timeoutMs <= 0 || timeoutMs > MAX_ACP_PREHEAT_TIMEOUT_MS)) {
        res.status(400).json({
          error: "`timeoutMs` must be a positive integer no greater than 60000",
          code: "invalid_timeout"
        });
        return;
      }
      res.status(200).json(
        await workspace.preheatAcpChild(ctx, {
          ...timeoutMs !== void 0 ? { timeoutMs } : {}
        })
      );
    } catch (err) {
      sendBridgeError2(res, err, { route: "POST /workspace/acp/preheat" });
    }
  });
  app.get("/workspace/acp/status", async (_req, res) => {
    try {
      const ctx = buildWorkspaceCtx("GET /workspace/acp/status");
      res.status(200).json(await workspace.getWorkspaceAcpStatus(ctx));
    } catch (err) {
      sendBridgeError2(res, err, { route: "GET /workspace/acp/status" });
    }
  });
  app.get("/workspace/tools", async (_req, res) => {
    try {
      res.status(200).json(await bridge.getWorkspaceToolsStatus());
    } catch (err) {
      sendBridgeError2(res, err, { route: "GET /workspace/tools" });
    }
  });
  app.get("/workspace/providers", async (_req, res) => {
    try {
      const ctx = buildWorkspaceCtx("GET /workspace/providers");
      res.status(200).json(await workspace.getWorkspaceProvidersStatus(ctx));
    } catch (err) {
      sendBridgeError2(res, err, { route: "GET /workspace/providers" });
    }
  });
}
__name(registerWorkspaceStatusRoutes, "registerWorkspaceStatusRoutes");
function resolveTrustedRuntime(registry, req, res) {
  const runtime = resolveWorkspaceRuntimeFromParam(registry, req, res);
  if (!runtime) return null;
  return requireTrustedWorkspaceRuntime(runtime, res) ? runtime : null;
}
__name(resolveTrustedRuntime, "resolveTrustedRuntime");
function registerWorkspaceQualifiedStatusRoutes(app, deps) {
  const { workspaceRegistry, sendBridgeError: sendBridgeError2 } = deps;
  app.get("/workspaces/:workspace/mcp", async (req, res) => {
    const runtime = resolveTrustedRuntime(workspaceRegistry, req, res);
    if (!runtime) return;
    const route = "GET /workspaces/:workspace/mcp";
    const ctx = createBuildWorkspaceCtx(runtime.workspaceCwd)(route);
    try {
      res.status(200).json(await runtime.workspaceService.getWorkspaceMcpStatus(ctx));
    } catch (err) {
      sendBridgeError2(res, err, { route });
    }
  });
  app.get("/workspaces/:workspace/mcp/:server/tools", async (req, res) => {
    const runtime = resolveTrustedRuntime(workspaceRegistry, req, res);
    if (!runtime) return;
    const serverName = req.params["server"];
    if (!serverName || typeof serverName !== "string") {
      res.status(400).json({
        error: "Server name path parameter is required",
        code: "invalid_server_name"
      });
      return;
    }
    if (serverName.length > MAX_SERVER_NAME_LENGTH) {
      res.status(400).json({
        error: `Server name exceeds ${MAX_SERVER_NAME_LENGTH}-character limit`,
        code: "invalid_server_name"
      });
      return;
    }
    const route = "GET /workspaces/:workspace/mcp/:server/tools";
    try {
      res.status(200).json(await runtime.bridge.getWorkspaceMcpToolsStatus(serverName));
    } catch (err) {
      sendBridgeError2(res, err, { route });
    }
  });
  app.get("/workspaces/:workspace/mcp/:server/resources", async (req, res) => {
    const runtime = resolveTrustedRuntime(workspaceRegistry, req, res);
    if (!runtime) return;
    const serverName = req.params["server"];
    if (!serverName || typeof serverName !== "string") {
      res.status(400).json({
        error: "Server name path parameter is required",
        code: "invalid_server_name"
      });
      return;
    }
    if (serverName.length > MAX_SERVER_NAME_LENGTH) {
      res.status(400).json({
        error: `Server name exceeds ${MAX_SERVER_NAME_LENGTH}-character limit`,
        code: "invalid_server_name"
      });
      return;
    }
    const route = "GET /workspaces/:workspace/mcp/:server/resources";
    try {
      res.status(200).json(await runtime.bridge.getWorkspaceMcpResourcesStatus(serverName));
    } catch (err) {
      sendBridgeError2(res, err, { route });
    }
  });
  app.get("/workspaces/:workspace/skills", async (req, res) => {
    const runtime = resolveTrustedRuntime(workspaceRegistry, req, res);
    if (!runtime) return;
    const route = "GET /workspaces/:workspace/skills";
    const ctx = createBuildWorkspaceCtx(runtime.workspaceCwd)(route);
    try {
      res.status(200).json(await runtime.workspaceService.getWorkspaceSkillsStatus(ctx));
    } catch (err) {
      sendBridgeError2(res, err, { route });
    }
  });
  app.get("/workspaces/:workspace/tools", async (req, res) => {
    const runtime = resolveTrustedRuntime(workspaceRegistry, req, res);
    if (!runtime) return;
    const route = "GET /workspaces/:workspace/tools";
    try {
      res.status(200).json(await runtime.bridge.getWorkspaceToolsStatus());
    } catch (err) {
      sendBridgeError2(res, err, { route });
    }
  });
  app.get("/workspaces/:workspace/providers", async (req, res) => {
    const runtime = resolveTrustedRuntime(workspaceRegistry, req, res);
    if (!runtime) return;
    const route = "GET /workspaces/:workspace/providers";
    const ctx = createBuildWorkspaceCtx(runtime.workspaceCwd)(route);
    try {
      res.status(200).json(await runtime.workspaceService.getWorkspaceProvidersStatus(ctx));
    } catch (err) {
      sendBridgeError2(res, err, { route });
    }
  });
}
__name(registerWorkspaceQualifiedStatusRoutes, "registerWorkspaceQualifiedStatusRoutes");
function registerWorkspaceDiagnosticStatusRoutes(app, deps) {
  const { boundWorkspace, workspace, sendBridgeError: sendBridgeError2 } = deps;
  const buildWorkspaceCtx = createBuildWorkspaceCtx(boundWorkspace);
  app.get("/workspace/env", async (_req, res) => {
    try {
      const ctx = buildWorkspaceCtx("GET /workspace/env");
      res.status(200).json(await workspace.getWorkspaceEnvStatus(ctx));
    } catch (err) {
      sendBridgeError2(res, err, { route: "GET /workspace/env" });
    }
  });
  app.get("/workspace/preflight", async (_req, res) => {
    try {
      const ctx = buildWorkspaceCtx("GET /workspace/preflight");
      res.status(200).json(await workspace.getWorkspacePreflightStatus(ctx));
    } catch (err) {
      sendBridgeError2(res, err, { route: "GET /workspace/preflight" });
    }
  });
  app.get("/workspace/hooks", async (_req, res) => {
    try {
      const ctx = buildWorkspaceCtx("GET /workspace/hooks");
      res.status(200).json(await workspace.getWorkspaceHooksStatus(ctx));
    } catch (err) {
      sendBridgeError2(res, err, { route: "GET /workspace/hooks" });
    }
  });
}
__name(registerWorkspaceDiagnosticStatusRoutes, "registerWorkspaceDiagnosticStatusRoutes");
function registerWorkspaceQualifiedDiagnosticStatusRoutes(app, deps) {
  const { workspaceRegistry, sendBridgeError: sendBridgeError2 } = deps;
  for (const [pathSuffix, methodName] of [
    ["env", "getWorkspaceEnvStatus"],
    ["preflight", "getWorkspacePreflightStatus"],
    ["hooks", "getWorkspaceHooksStatus"]
  ]) {
    app.get(`/workspaces/:workspace/${pathSuffix}`, async (req, res) => {
      const runtime = resolveTrustedRuntime(workspaceRegistry, req, res);
      if (!runtime) return;
      const route = `GET /workspaces/:workspace/${pathSuffix}`;
      const ctx = createBuildWorkspaceCtx(runtime.workspaceCwd)(route);
      try {
        res.status(200).json(await runtime.workspaceService[methodName](ctx));
      } catch (err) {
        sendBridgeError2(res, err, { route });
      }
    });
  }
}
__name(registerWorkspaceQualifiedDiagnosticStatusRoutes, "registerWorkspaceQualifiedDiagnosticStatusRoutes");

// packages/cli/src/serve/routes/capabilities.ts
init_esbuild_shims();

// packages/cli/src/serve/server/serve-features.ts
init_esbuild_shims();
var DEFAULT_MAX_SESSIONS = 20;
var DEFAULT_MAX_PENDING_PROMPTS_PER_SESSION = 5;
var SERVE_LANGUAGE_CODES = [
  ...SUPPORTED_LANGUAGES.map((language) => language.code),
  "auto"
];
function advertisedMaxPendingPromptsPerSession(value) {
  if (value === void 0) return DEFAULT_MAX_PENDING_PROMPTS_PER_SESSION;
  if (value === 0 || value === Number.POSITIVE_INFINITY) return null;
  return value;
}
__name(advertisedMaxPendingPromptsPerSession, "advertisedMaxPendingPromptsPerSession");
function advertisedMaxSessions(value) {
  if (value === void 0) return DEFAULT_MAX_SESSIONS;
  if (value === 0 || value === Number.POSITIVE_INFINITY) return null;
  return value;
}
__name(advertisedMaxSessions, "advertisedMaxSessions");
function createServeFeatures(deps) {
  const {
    opts,
    boundWorkspace,
    persistSettingAvailable,
    sessionArtifactsPersistenceAvailable,
    sessionGenerationAvailable,
    reloadAvailable,
    channelReloadAvailable,
    channelControlAvailable,
    sessionShellCommandEnabled,
    multiWorkspaceSessionsEnabled,
    persistentWorkspaceRegistrationAvailable,
    workspaceRuntimeRemovalAvailable
  } = deps;
  const env = deps.env ?? process.env;
  let cachedVoiceTranscriptionAvailable;
  const invalidateServeFeaturesCache = /* @__PURE__ */ __name(() => {
    cachedVoiceTranscriptionAvailable = void 0;
  }, "invalidateServeFeaturesCache");
  const getCachedVoiceTranscriptionAvailable = /* @__PURE__ */ __name(() => {
    cachedVoiceTranscriptionAvailable ??= isWorkspaceVoiceTranscriptionAvailable(
      boundWorkspace,
      env,
      deps.env !== void 0
    );
    return cachedVoiceTranscriptionAvailable;
  }, "getCachedVoiceTranscriptionAvailable");
  return {
    languageCodes: SERVE_LANGUAGE_CODES,
    invalidateServeFeaturesCache,
    currentServeFeatures: /* @__PURE__ */ __name(() => getAdvertisedServeFeatures(void 0, {
      requireAuth: opts.requireAuth === true,
      mcpPoolActive: opts.mcpPoolActive !== false,
      allowOriginActive: opts.allowOrigins !== void 0 && opts.allowOrigins.length > 0,
      ...opts.promptDeadlineMs !== void 0 ? { promptDeadlineMs: opts.promptDeadlineMs } : {},
      ...opts.writerIdleTimeoutMs !== void 0 ? { writerIdleTimeoutMs: opts.writerIdleTimeoutMs } : {},
      persistSettingAvailable,
      sessionShellCommandEnabled,
      sessionArtifactsPersistenceAvailable,
      sessionGenerationAvailable: sessionGenerationAvailable(),
      rateLimit: opts.rateLimit === true,
      reloadAvailable,
      channelReloadAvailable: channelReloadAvailable(),
      channelControlAvailable,
      multiWorkspaceSessionsEnabled: multiWorkspaceSessionsEnabled(),
      persistentWorkspaceRegistrationAvailable,
      workspaceRuntimeRemovalAvailable,
      acpHttpEnabled: resolveAcpHttpEnabled(),
      clientMcpOverWsEnabled: opts.clientMcpOverWs === true,
      cdpTunnelOverWsEnabled: opts.cdpTunnelOverWs === true,
      browserAutomationMcpAvailable: isBrowserAutomationMcpAvailable(
        opts,
        env
      ),
      voiceTranscriptionAvailable: getCachedVoiceTranscriptionAvailable(),
      // Advertised whenever the `/voice/stream` WS endpoint exists (ACP HTTP
      // on). A configured token no longer suppresses it — the browser carries
      // the bearer token via the WS subprotocol, which the upgrade listener
      // verifies (acp-http/index.ts).
      voiceWsAvailable: resolveAcpHttpEnabled(env)
    }), "currentServeFeatures")
  };
}
__name(createServeFeatures, "createServeFeatures");
function isWorkspaceVoiceTranscriptionAvailable(boundWorkspace, env, skipLoadEnvironment) {
  try {
    return hasConfiguredBatchVoiceTranscriptionModel(
      loadSettings(boundWorkspace, { skipLoadEnvironment }),
      { env }
    );
  } catch (err) {
    writeStderrLine(
      `qwen serve: workspace voice transcription capability check failed: ${err instanceof Error ? err.message : String(err)}`
    );
    return false;
  }
}
__name(isWorkspaceVoiceTranscriptionAvailable, "isWorkspaceVoiceTranscriptionAvailable");

// packages/cli/src/serve/routes/capabilities.ts
function registerCapabilitiesRoutes(app, deps) {
  app.get("/capabilities", (_req, res) => {
    const runtimes = deps.workspaceRegistry.list();
    const multiWorkspace = runtimes.length > 1;
    const features = deps.currentServeFeatures();
    const runtimeRemoval = features.includes("workspace_runtime_removal");
    const envelope = {
      v: CAPABILITIES_SCHEMA_VERSION,
      protocolVersions: getServeProtocolVersions(),
      ...deps.qwenCodeVersion ? { qwenCodeVersion: deps.qwenCodeVersion } : {},
      mode: deps.mode,
      features,
      modelServices: [],
      // Surface the primary workspace so clients can omit `cwd` on
      // `POST /session`; multi-workspace clients use `workspaces[]`.
      workspaceCwd: deps.boundWorkspace,
      // Advertise supported transport families so SDK clients can
      // auto-negotiate the best available transport via negotiateTransport().
      transports: ["rest"],
      // Active mediation policy under the `policy` namespace.
      policy: { permission: deps.permissionPolicy },
      limits: {
        maxPendingPromptsPerSession: advertisedMaxPendingPromptsPerSession(
          deps.maxPendingPromptsPerSession
        ),
        ...multiWorkspace ? {
          maxSessionsPerWorkspace: advertisedMaxSessions(
            deps.maxSessionsPerWorkspace
          ),
          maxTotalSessions: deps.maxTotalSessions === void 0 || deps.maxTotalSessions === 0 || deps.maxTotalSessions === Number.POSITIVE_INFINITY ? null : deps.maxTotalSessions
        } : {}
      },
      workspaces: runtimes.map((runtime) => ({
        id: runtime.workspaceId,
        cwd: runtime.workspaceCwd,
        primary: runtime.primary,
        trusted: runtime.trusted,
        ...runtimeRemoval ? { removable: runtime.removable === true } : {}
      })),
      supportedLanguages: deps.languageCodes
    };
    res.status(200).json(envelope);
  });
}
__name(registerCapabilitiesRoutes, "registerCapabilitiesRoutes");

// packages/cli/src/serve/routes/workspace-permissions.ts
init_esbuild_shims();
function registerWorkspacePermissionsRoutes(app, deps) {
  const {
    boundWorkspace,
    mutate,
    safeBody: safeBody2,
    workspace,
    parseAndValidateClientId
  } = deps;
  app.get("/workspace/permissions", (_req, res) => {
    try {
      res.status(200).json(buildPermissionSettings(loadSettings(boundWorkspace)));
    } catch (err) {
      writeStderrLine(
        `qwen serve: GET /workspace/permissions error: ${err instanceof Error ? err.message : String(err)}`
      );
      res.status(500).json({
        error: "Failed to load permission rules",
        code: "internal_error"
      });
    }
  });
  app.post(
    "/workspace/permissions",
    mutate({ strict: true }),
    async (req, res) => {
      const body = safeBody2(req);
      const scope = body["scope"];
      const ruleType = body["ruleType"];
      if (scope !== "user" && scope !== "workspace") {
        res.status(400).json({
          error: 'scope must be "user" or "workspace"',
          code: "invalid_scope"
        });
        return;
      }
      const permissionScope = scope;
      if (!isPermissionRuleType(ruleType)) {
        res.status(400).json({
          error: 'ruleType must be "allow", "ask", or "deny"',
          code: "invalid_rule_type"
        });
        return;
      }
      let rules;
      try {
        const settings = loadSettings(boundWorkspace);
        const scopeSettings = permissionScope === "workspace" ? settings.workspace.settings : settings.user.settings;
        const existingRules = readPermissionRuleSet(scopeSettings)[ruleType];
        rules = normalizePermissionRules(body["rules"], { existingRules });
      } catch (err) {
        if (err instanceof PermissionRulesValidationError) {
          res.status(400).json({
            error: err.message,
            code: err.code
          });
          return;
        }
        throw err;
      }
      const clientId = parseAndValidateClientId(req, res);
      if (clientId === null) return;
      const key = `permissions.${ruleType}`;
      let liveResponse;
      try {
        liveResponse = await workspace.setWorkspacePermissionRules(
          {
            route: "POST /workspace/permissions",
            workspaceCwd: boundWorkspace,
            ...clientId ? { originatorClientId: clientId } : {}
          },
          { scope: permissionScope, ruleType, rules }
        );
      } catch (err) {
        if (err instanceof WorkspacePermissionRulesSessionRequiredError) {
          res.status(409).json({
            error: "A live ACP session is required to update active permission rules.",
            code: "permission_session_required"
          });
          return;
        }
        writeStderrLine(
          `qwen serve: POST /workspace/permissions ACP error (key=${key}, scope=${permissionScope}, workspace=${boundWorkspace}): ${err instanceof Error ? err.message : String(err)}`
        );
        res.status(500).json({
          error: "Failed to update permission rules",
          code: "permission_update_failed"
        });
        return;
      }
      res.status(200).json(liveResponse);
    }
  );
}
__name(registerWorkspacePermissionsRoutes, "registerWorkspacePermissionsRoutes");
function registerWorkspaceQualifiedPermissionsRoutes(app, deps) {
  app.get("/workspaces/:workspace/permissions", (req, res) => {
    const runtime = resolveWorkspaceRuntimeFromParam(
      deps.workspaceRegistry,
      req,
      res
    );
    if (!runtime || !requireTrustedWorkspaceRuntime(runtime, res)) return;
    try {
      res.status(200).json(buildPermissionSettings(loadSettings(runtime.workspaceCwd)));
    } catch (err) {
      writeStderrLine(
        `qwen serve: GET /workspaces/:workspace/permissions error: ${err instanceof Error ? err.message : String(err)}`
      );
      res.status(500).json({
        error: "Failed to load permission rules",
        code: "internal_error"
      });
    }
  });
  app.post(
    "/workspaces/:workspace/permissions",
    deps.mutate({ strict: true }),
    async (req, res) => {
      const runtime = resolveWorkspaceRuntimeFromParam(
        deps.workspaceRegistry,
        req,
        res
      );
      if (!runtime || !requireTrustedWorkspaceRuntime(runtime, res)) return;
      const body = deps.safeBody(req);
      const scope = body["scope"];
      const ruleType = body["ruleType"];
      if (scope !== "workspace") {
        res.status(400).json({
          error: 'workspace-qualified permissions routes only support "workspace" scope',
          code: "global_scope_not_supported_for_workspace_route"
        });
        return;
      }
      const permissionScope = "workspace";
      if (!isPermissionRuleType(ruleType)) {
        res.status(400).json({
          error: 'ruleType must be "allow", "ask", or "deny"',
          code: "invalid_rule_type"
        });
        return;
      }
      let rules;
      try {
        const settings = loadSettings(runtime.workspaceCwd);
        const existingRules = readPermissionRuleSet(
          settings.workspace.settings
        )[ruleType];
        rules = normalizePermissionRules(body["rules"], { existingRules });
      } catch (err) {
        if (err instanceof PermissionRulesValidationError) {
          res.status(400).json({
            error: err.message,
            code: err.code
          });
          return;
        }
        throw err;
      }
      const clientId = parseAndValidateWorkspaceClientId(
        req,
        res,
        runtime.bridge
      );
      if (clientId === null) return;
      try {
        const liveResponse = await runtime.workspaceService.setWorkspacePermissionRules(
          {
            route: "POST /workspaces/:workspace/permissions",
            workspaceCwd: runtime.workspaceCwd,
            ...clientId ? { originatorClientId: clientId } : {}
          },
          { scope: permissionScope, ruleType, rules }
        );
        res.status(200).json(liveResponse);
      } catch (err) {
        if (err instanceof WorkspacePermissionRulesSessionRequiredError) {
          res.status(409).json({
            error: "A live ACP session is required to update active permission rules.",
            code: "permission_session_required"
          });
          return;
        }
        writeStderrLine(
          `qwen serve: POST /workspaces/:workspace/permissions ACP error (ruleType=${ruleType}, workspace=${runtime.workspaceCwd}): ${err instanceof Error ? err.message : String(err)}`
        );
        res.status(500).json({
          error: "Failed to update permission rules",
          code: "permission_update_failed"
        });
      }
    }
  );
}
__name(registerWorkspaceQualifiedPermissionsRoutes, "registerWorkspaceQualifiedPermissionsRoutes");

// packages/cli/src/serve/routes/workspace-settings.ts
init_esbuild_shims();
var TUI_ONLY_SETTINGS = /* @__PURE__ */ new Set([
  "general.vimMode",
  "general.terminalBell",
  "general.notificationMode",
  "general.preferredEditor",
  "general.outputLanguage",
  "ide.enabled",
  "ui.showLineNumbers",
  "ui.renderMode",
  "ui.useTerminalBuffer",
  "ui.hideBanner",
  "ui.accessibility.enableLoadingPhrases",
  "ui.enableWelcomeBack"
]);
var WEB_SHELL_SETTINGS = /* @__PURE__ */ new Set([
  "ui.compactMode",
  "voiceModel",
  "mcpServers"
]);
var VALID_WRITE_SCOPES = /* @__PURE__ */ new Set(["workspace", "user"]);
var QUALIFIED_WRITE_SCOPES = /* @__PURE__ */ new Set(["workspace"]);
var mcpServerMutationQueues = /* @__PURE__ */ new Map();
var SECURITY_SENSITIVE_SETTINGS = /* @__PURE__ */ new Set(["tools.approvalMode"]);
function getAllowedKeys() {
  const keys = new Set(
    getDialogSettingKeys().filter(
      (k) => !TUI_ONLY_SETTINGS.has(k) && !SECURITY_SENSITIVE_SETTINGS.has(k)
    )
  );
  for (const key of WEB_SHELL_SETTINGS) {
    keys.add(key);
  }
  return keys;
}
__name(getAllowedKeys, "getAllowedKeys");
function buildSettingsResponse(boundWorkspace, keys) {
  const loaded = loadSettings(boundWorkspace);
  const settings = [];
  for (const key of keys) {
    const def = getSettingDefinition(key);
    if (!def) continue;
    const effective = getNestedProperty(
      loaded.merged,
      key
    );
    const userVal = getNestedProperty(
      loaded.user.settings,
      key
    );
    const wsVal = getNestedProperty(
      loaded.workspace.settings,
      key
    );
    const publicValue = /* @__PURE__ */ __name((value) => key === "mcpServers" ? redactMcpServersSetting(value) : value, "publicValue");
    const values = {
      effective: publicValue(effective !== void 0 ? effective : def.default)
    };
    if (userVal !== void 0) values.user = publicValue(userVal);
    if (wsVal !== void 0) values.workspace = publicValue(wsVal);
    settings.push({
      key,
      type: def.type,
      label: def.label,
      category: def.category,
      ...def.description ? { description: def.description } : {},
      requiresRestart: def.requiresRestart,
      default: def.default,
      ...def.options?.length ? { options: def.options } : {},
      values
    });
  }
  const warnings = [];
  if (loaded.corruptedPath) {
    warnings.push({
      type: "corrupted",
      recovered: loaded.wasRecovered
    });
  }
  return {
    v: 1,
    ...warnings.length ? { warnings } : {},
    settings
  };
}
__name(buildSettingsResponse, "buildSettingsResponse");
var SCOPE_MAP = {
  user: "User" /* User */,
  workspace: "Workspace" /* Workspace */
};
function prepareSettingWrite(workspace, scope, key, value, mcpServerMutation) {
  if (key !== "mcpServers") {
    return { persistedValue: value, publicValue: value };
  }
  const existing = loadSettings(workspace).forScope(scope).settings.mcpServers ?? {};
  let nextValue = value;
  if (mcpServerMutation) {
    const servers = { ...existing };
    if (mcpServerMutation.operation === "set") {
      servers[mcpServerMutation.name] = value;
    } else {
      delete servers[mcpServerMutation.name];
    }
    nextValue = servers;
  }
  const persistedValue = restoreRedactedMcpServersSetting(nextValue, existing);
  return {
    persistedValue,
    publicValue: redactMcpServersSetting(persistedValue)
  };
}
__name(prepareSettingWrite, "prepareSettingWrite");
function parseMcpServerMutation(key, value) {
  if (value === void 0) return void 0;
  if (key !== "mcpServers" || typeof value !== "object" || value === null) {
    throw new Error("mcpServerMutation is only valid for mcpServers");
  }
  const operation = value["operation"];
  const name = value["name"];
  if (operation !== "set" && operation !== "remove" || typeof name !== "string" || !name.trim()) {
    throw new Error("mcpServerMutation requires a valid operation and name");
  }
  return { operation, name };
}
__name(parseMcpServerMutation, "parseMcpServerMutation");
async function withMcpServerMutationLock(workspace, scope, operation) {
  const key = `${workspace}\0${scope}`;
  const previous = mcpServerMutationQueues.get(key) ?? Promise.resolve();
  const run = previous.catch(() => void 0).then(operation);
  const tail = run.then(
    () => void 0,
    () => void 0
  );
  mcpServerMutationQueues.set(key, tail);
  try {
    return await run;
  } finally {
    if (mcpServerMutationQueues.get(key) === tail) {
      mcpServerMutationQueues.delete(key);
    }
  }
}
__name(withMcpServerMutationLock, "withMcpServerMutationLock");
function registerWorkspaceSettingsRoutes(app, deps) {
  const {
    boundWorkspace,
    mutate,
    safeBody: safeBody2,
    persistSetting,
    broadcastSettingsChanged,
    parseAndValidateClientId
  } = deps;
  const allowedKeys = getAllowedKeys();
  app.get("/workspace/settings", (_req, res) => {
    try {
      const response = buildSettingsResponse(boundWorkspace, allowedKeys);
      res.status(200).json(response);
    } catch (err) {
      writeStderrLine(
        `qwen serve: GET /workspace/settings error: ${err instanceof Error ? err.message : String(err)}`
      );
      res.status(500).json({
        error: "Failed to load settings",
        code: "internal_error"
      });
    }
  });
  app.post(
    "/workspace/settings",
    mutate({ strict: true }),
    async (req, res) => {
      const body = safeBody2(req);
      const scope = body["scope"];
      const key = body["key"];
      const value = body["value"];
      let mcpServerMutation;
      try {
        mcpServerMutation = parseMcpServerMutation(
          typeof key === "string" ? key : "",
          body["mcpServerMutation"]
        );
      } catch (error2) {
        res.status(400).json({
          error: error2 instanceof Error ? error2.message : String(error2),
          code: "invalid_mcp_server_mutation"
        });
        return;
      }
      if (typeof scope !== "string" || !VALID_WRITE_SCOPES.has(scope)) {
        res.status(400).json({
          error: `scope must be one of: ${[...VALID_WRITE_SCOPES].join(", ")}`,
          code: "invalid_scope"
        });
        return;
      }
      if (typeof key !== "string" || !key) {
        res.status(400).json({
          error: "key is required and must be a string",
          code: "invalid_key"
        });
        return;
      }
      if (!allowedKeys.has(key)) {
        res.status(400).json({
          error: `Setting "${key}" is not modifiable via this API`,
          code: "disallowed_key"
        });
        return;
      }
      if (value === void 0 || value === null) {
        res.status(400).json({
          error: "value is required",
          code: "missing_value"
        });
        return;
      }
      const def = getSettingDefinition(key);
      if (!def) {
        res.status(400).json({
          error: `Unknown setting: ${key}`,
          code: "unknown_key"
        });
        return;
      }
      const validationError = validateSettingValue(def, value);
      if (validationError) {
        res.status(400).json({
          error: validationError,
          code: "invalid_value"
        });
        return;
      }
      const clientId = parseAndValidateClientId(req, res);
      if (clientId === null) return;
      const settingScope = SCOPE_MAP[scope];
      if (!settingScope) {
        res.status(400).json({
          error: `scope must be one of: ${[...VALID_WRITE_SCOPES].join(", ")}`,
          code: "invalid_scope"
        });
        return;
      }
      let publicValue = value;
      try {
        const persist = /* @__PURE__ */ __name(async () => {
          const prepared = prepareSettingWrite(
            boundWorkspace,
            settingScope,
            key,
            value,
            mcpServerMutation
          );
          publicValue = prepared.publicValue;
          await persistSetting(
            boundWorkspace,
            settingScope,
            key,
            prepared.persistedValue
          );
        }, "persist");
        if (mcpServerMutation) {
          await withMcpServerMutationLock(
            boundWorkspace,
            settingScope,
            persist
          );
        } else {
          await persist();
        }
      } catch (err) {
        writeStderrLine(
          `qwen serve: POST /workspace/settings persist error (key=${key}, scope=${scope}, workspace=${boundWorkspace}): ${err instanceof Error ? err.message : String(err)}`
        );
        res.status(500).json({
          error: "Failed to persist setting",
          code: "persist_error"
        });
        return;
      }
      try {
        broadcastSettingsChanged(key, publicValue, scope, clientId);
      } catch (err) {
        writeStderrLine(
          `qwen serve: POST /workspace/settings broadcast error (key=${key}, scope=${scope}): ${err instanceof Error ? err.message : String(err)}`
        );
      }
      res.status(200).json({
        key,
        scope,
        value: publicValue,
        requiresRestart: def.requiresRestart
      });
    }
  );
}
__name(registerWorkspaceSettingsRoutes, "registerWorkspaceSettingsRoutes");
function registerWorkspaceQualifiedSettingsRoutes(app, deps) {
  const allowedKeys = getAllowedKeys();
  app.get("/workspaces/:workspace/settings", (req, res) => {
    const runtime = resolveWorkspaceRuntimeFromParam(
      deps.workspaceRegistry,
      req,
      res
    );
    if (!runtime || !requireTrustedWorkspaceRuntime(runtime, res)) return;
    try {
      const response = buildSettingsResponse(runtime.workspaceCwd, allowedKeys);
      res.status(200).json(response);
    } catch (err) {
      writeStderrLine(
        `qwen serve: GET /workspaces/:workspace/settings error: ${err instanceof Error ? err.message : String(err)}`
      );
      res.status(500).json({
        error: "Failed to load settings",
        code: "internal_error"
      });
    }
  });
  app.post(
    "/workspaces/:workspace/settings",
    deps.mutate({ strict: true }),
    async (req, res) => {
      const runtime = resolveWorkspaceRuntimeFromParam(
        deps.workspaceRegistry,
        req,
        res
      );
      if (!runtime || !requireTrustedWorkspaceRuntime(runtime, res)) return;
      const body = deps.safeBody(req);
      const scope = body["scope"];
      const key = body["key"];
      const value = body["value"];
      let mcpServerMutation;
      try {
        mcpServerMutation = parseMcpServerMutation(
          typeof key === "string" ? key : "",
          body["mcpServerMutation"]
        );
      } catch (error2) {
        res.status(400).json({
          error: error2 instanceof Error ? error2.message : String(error2),
          code: "invalid_mcp_server_mutation"
        });
        return;
      }
      if (typeof scope !== "string" || !QUALIFIED_WRITE_SCOPES.has(scope)) {
        res.status(400).json({
          error: `scope must be one of: ${[...QUALIFIED_WRITE_SCOPES].join(", ")}`,
          code: "invalid_scope"
        });
        return;
      }
      if (typeof key !== "string" || !key) {
        res.status(400).json({
          error: "key is required and must be a string",
          code: "invalid_key"
        });
        return;
      }
      if (!allowedKeys.has(key)) {
        res.status(400).json({
          error: `Setting "${key}" is not modifiable via this API`,
          code: "disallowed_key"
        });
        return;
      }
      if (value === void 0 || value === null) {
        res.status(400).json({
          error: "value is required",
          code: "missing_value"
        });
        return;
      }
      const def = getSettingDefinition(key);
      if (!def) {
        res.status(400).json({
          error: `Unknown setting: ${key}`,
          code: "unknown_key"
        });
        return;
      }
      const validationError = validateSettingValue(def, value);
      if (validationError) {
        res.status(400).json({
          error: validationError,
          code: "invalid_value"
        });
        return;
      }
      const clientId = parseAndValidateWorkspaceClientId(
        req,
        res,
        runtime.bridge
      );
      if (clientId === null) return;
      const settingScope = SCOPE_MAP[scope];
      if (!settingScope) {
        res.status(400).json({
          error: `scope must be one of: ${[...QUALIFIED_WRITE_SCOPES].join(", ")}`,
          code: "invalid_scope"
        });
        return;
      }
      let publicValue = value;
      try {
        const persist = /* @__PURE__ */ __name(async () => {
          const prepared = prepareSettingWrite(
            runtime.workspaceCwd,
            settingScope,
            key,
            value,
            mcpServerMutation
          );
          publicValue = prepared.publicValue;
          await deps.persistSetting(
            runtime.workspaceCwd,
            settingScope,
            key,
            prepared.persistedValue
          );
        }, "persist");
        if (mcpServerMutation) {
          await withMcpServerMutationLock(
            runtime.workspaceCwd,
            settingScope,
            persist
          );
        } else {
          await persist();
        }
      } catch (err) {
        writeStderrLine(
          `qwen serve: POST /workspaces/:workspace/settings persist error (key=${key}, scope=${scope}, workspace=${runtime.workspaceCwd}): ${err instanceof Error ? err.message : String(err)}`
        );
        res.status(500).json({
          error: "Failed to persist setting",
          code: "persist_error"
        });
        return;
      }
      deps.invalidateServeFeaturesCache();
      runtime.bridge.publishWorkspaceEvent({
        type: "settings_changed",
        data: { key, value: publicValue, scope },
        ...clientId ? { originatorClientId: clientId } : {}
      });
      res.status(200).json({
        key,
        scope,
        value: publicValue,
        requiresRestart: def.requiresRestart
      });
    }
  );
}
__name(registerWorkspaceQualifiedSettingsRoutes, "registerWorkspaceQualifiedSettingsRoutes");

// packages/cli/src/serve/routes/sse-events.ts
init_esbuild_shims();

// packages/cli/src/serve/server/error-response.ts
init_esbuild_shims();
function bridgeErrorExtraContext(ctx) {
  const extra = {};
  for (const [key, value] of Object.entries(ctx ?? {})) {
    if (key === "route" || key === "sessionId" || value === void 0) {
      continue;
    }
    extra[key] = value;
  }
  return extra;
}
__name(bridgeErrorExtraContext, "bridgeErrorExtraContext");
function sendPermissionVoteError(res, err, ctx, daemonLog) {
  if (err instanceof InvalidPermissionOptionError) {
    res.status(400).json({
      error: err.message,
      code: "invalid_option_id",
      requestId: err.requestId,
      optionId: err.optionId
    });
    return;
  }
  if (err instanceof PermissionForbiddenError) {
    res.status(403).json({
      error: err.message,
      code: "permission_forbidden",
      requestId: err.requestId,
      sessionId: err.sessionId,
      reason: err.reason
    });
    return;
  }
  if (err instanceof PermissionPolicyNotImplementedError) {
    res.status(501).json({
      error: err.message,
      code: "permission_policy_not_implemented",
      policy: err.policy
    });
    return;
  }
  if (err instanceof CancelSentinelCollisionError) {
    res.status(500).json({
      error: err.message,
      code: "cancel_sentinel_collision",
      requestId: err.requestId,
      sentinel: err.sentinel
    });
    return;
  }
  sendBridgeError(res, err, ctx, daemonLog);
}
__name(sendPermissionVoteError, "sendPermissionVoteError");
function sendBridgeError(res, err, ctx, daemonLog) {
  if (err instanceof WorkspaceSkillNotFoundError) {
    res.status(404).json({
      error: err.message,
      code: "skill_not_found",
      skillName: err.skillName
    });
    return;
  }
  if (err instanceof WorkspaceSkillNotToggleableError) {
    res.status(409).json({
      error: err.message,
      code: "skill_not_toggleable",
      skillName: err.skillName,
      reason: err.reason,
      ...err.lockedScope ? { lockedScope: err.lockedScope } : {}
    });
    return;
  }
  if (err instanceof InvalidSessionTranscriptCursorError) {
    res.status(400).json({
      error: err.message,
      code: "invalid_transcript_cursor",
      ...ctx?.sessionId ? { sessionId: ctx.sessionId } : {}
    });
    return;
  }
  if (err instanceof SessionTranscriptSnapshotUnavailableError) {
    res.status(409).json({
      error: err.message,
      code: "transcript_snapshot_unavailable",
      ...ctx?.sessionId ? { sessionId: ctx.sessionId } : {}
    });
    return;
  }
  if (err instanceof SessionTranscriptPageTooLargeError) {
    res.status(413).json({
      error: err.message,
      code: "transcript_page_too_large",
      sessionId: err.sessionId,
      pageBytes: err.pageBytes,
      maxBytes: err.maxBytes
    });
    return;
  }
  if (err instanceof SessionTranscriptTooLargeError) {
    res.status(413).json({
      error: err.message,
      code: "transcript_too_large",
      sessionId: err.sessionId,
      snapshotSize: err.snapshotSize,
      maxBytes: err.maxBytes
    });
    return;
  }
  if (err instanceof WorkspaceDrainingError) {
    res.set("Retry-After", "5");
    res.status(503).json({
      error: err.message,
      code: "workspace_draining",
      workspaceCwd: err.workspaceCwd
    });
    return;
  }
  if (err instanceof WorkspaceInitConflictError) {
    res.status(409).json({
      error: err.message,
      code: "workspace_init_conflict",
      path: err.path,
      existingSize: err.existingSize
    });
    return;
  }
  if (err instanceof WorkspaceInitPathEscapeError) {
    res.status(400).json({
      error: err.message,
      code: "workspace_init_path_escape",
      filename: err.filename,
      boundWorkspace: err.boundWorkspace
    });
    return;
  }
  if (err instanceof WorkspaceInitSymlinkError) {
    res.status(400).json({
      error: err.message,
      code: "workspace_init_symlink",
      target: err.target,
      kind: err.kind
    });
    return;
  }
  if (err instanceof WorkspaceInitRaceError) {
    res.status(400).json({
      error: err.message,
      code: "workspace_init_race",
      target: err.target,
      kind: err.kind
    });
    return;
  }
  if (err instanceof McpServerNotFoundError) {
    res.status(404).json({
      error: err.message,
      code: "mcp_server_not_found",
      serverName: err.serverName
    });
    return;
  }
  if (err instanceof McpServerRestartFailedError) {
    res.status(502).json({
      error: err.message,
      code: "mcp_server_restart_failed",
      errorKind: "protocol_error",
      serverName: err.serverName,
      mcpStatus: err.mcpStatus
    });
    return;
  }
  if (err instanceof BranchWhilePromptActiveError) {
    res.status(409).json({
      error: err.message,
      code: "branch_while_prompt_active",
      sessionId: err.sessionId
    });
    return;
  }
  if (err instanceof CdWhilePromptActiveError) {
    res.status(409).json({
      error: err.message,
      code: "cd_while_prompt_active",
      sessionId: err.sessionId
    });
    return;
  }
  if (err instanceof TrustGateError) {
    res.status(403).json({
      error: err.message,
      code: "trust_gate",
      errorKind: "auth_env_error"
    });
    return;
  }
  if (err instanceof SessionNotFoundError) {
    res.status(404).json({ error: err.message, sessionId: err.sessionId });
    return;
  }
  if (err instanceof SessionArchivedError) {
    res.status(409).json({
      error: err.message,
      code: "session_archived",
      sessionId: err.sessionId
    });
    return;
  }
  if (err instanceof SessionNotArchivedError) {
    res.status(409).json({
      error: err.message,
      code: "session_not_archived",
      sessionId: err.sessionId
    });
    return;
  }
  if (err instanceof SessionConflictError) {
    res.status(409).json({
      error: err.message,
      code: "session_conflict",
      sessionId: err.sessionId
    });
    return;
  }
  if (err instanceof SessionArchivingError) {
    res.set("Retry-After", "5");
    res.status(409).json({
      error: err.message,
      code: "session_archiving",
      sessionId: err.sessionId
    });
    return;
  }
  if (err instanceof InvalidClientIdError) {
    res.status(400).json({
      error: err.message,
      code: "invalid_client_id",
      sessionId: err.sessionId,
      clientId: err.clientId
    });
    return;
  }
  if (err instanceof SessionArtifactAuthorizationError) {
    res.status(403).json({
      error: err.message,
      code: "session_artifact_forbidden",
      sessionId: err.sessionId,
      artifactId: err.artifactId
    });
    return;
  }
  if (err instanceof SessionShellDisabledError) {
    res.status(403).json({
      error: err.message,
      code: "session_shell_disabled",
      errorKind: "session_shell_disabled"
    });
    return;
  }
  if (err instanceof SessionShellClientRequiredError) {
    res.status(403).json({
      error: err.message,
      code: "client_id_required",
      errorKind: "client_id_required"
    });
    return;
  }
  if (err instanceof WorkspaceMismatchError) {
    writeStderrLine(
      `qwen serve: workspace_mismatch (POST /session): daemon bound to ${JSON.stringify(err.bound)}, rejected ${JSON.stringify(err.requested)}`
    );
    res.status(400).json({
      error: err.message,
      code: "workspace_mismatch",
      boundWorkspace: err.bound,
      requestedWorkspace: err.requested
    });
    return;
  }
  if (err instanceof InvalidSessionScopeError) {
    res.status(400).json({
      error: err.message,
      code: "invalid_session_scope"
    });
    return;
  }
  if (err instanceof InvalidSessionMetadataError) {
    res.status(400).json({
      error: err.message,
      code: "invalid_metadata",
      field: err.field
    });
    return;
  }
  if (err instanceof SessionLimitExceededError) {
    res.set("Retry-After", "5");
    res.status(503).json({
      error: err.message,
      code: "session_limit_exceeded",
      limit: err.limit,
      scope: "workspace"
    });
    return;
  }
  if (err instanceof TotalSessionLimitExceededError) {
    const totalSessionError = err;
    daemonLog?.warn("total session admission rejected", {
      ...ctx?.route ? { route: ctx.route } : {},
      ...ctx?.sessionId ? { sessionId: ctx.sessionId } : {},
      limit: totalSessionError.limit,
      scope: totalSessionError.scope,
      ...totalSessionError.operation ? { operation: totalSessionError.operation } : {},
      ...totalSessionError.workspaceCwd ? { workspaceCwd: totalSessionError.workspaceCwd } : {},
      ...totalSessionError.sourceSessionId ? { sourceSessionId: totalSessionError.sourceSessionId } : {}
    });
    res.set("Retry-After", "5");
    res.status(503).json({
      error: err.message,
      code: "session_limit_exceeded",
      limit: err.limit,
      scope: err.scope
    });
    return;
  }
  if (err instanceof PromptQueueFullError) {
    res.set("Retry-After", "5");
    res.status(503).json({
      error: err.message,
      code: "prompt_queue_full",
      sessionId: err.sessionId,
      limit: err.limit,
      pendingCount: err.pendingCount
    });
    return;
  }
  if (err instanceof RestoreInProgressError) {
    res.set("Retry-After", "5");
    res.status(409).json({
      error: err.message,
      code: "restore_in_progress",
      sessionId: err.sessionId,
      activeAction: err.activeAction,
      requestedAction: err.requestedAction
    });
    return;
  }
  if (err instanceof SessionBusyError) {
    res.set("Retry-After", "5");
    res.status(409).json({
      error: err.message,
      code: "session_busy",
      sessionId: err.sessionId
    });
    return;
  }
  if (err instanceof InvalidRewindTargetError) {
    res.status(400).json({
      error: err.message,
      code: "invalid_rewind_target",
      sessionId: err.sessionId
    });
    return;
  }
  if (err && typeof err === "object") {
    const data = err.data;
    if (data && typeof data === "object") {
      const kind = data.errorKind;
      if (kind === "mcp_budget_would_exceed") {
        const d = data;
        res.status(409).json({
          error: errorMessage2(err),
          code: "mcp_budget_would_exceed",
          serverName: d.serverName
        });
        return;
      }
      if (kind === "mcp_server_spawn_failed") {
        const d = data;
        res.status(502).json({
          error: errorMessage2(err),
          code: "mcp_server_spawn_failed",
          serverName: d.serverName,
          exitCode: d.exitCode,
          stderr: d.stderr,
          ...d.timeout !== void 0 ? { timeout: d.timeout } : {}
        });
        return;
      }
      if (kind === "invalid_config") {
        const d = data;
        res.status(400).json({
          error: errorMessage2(err),
          code: "invalid_config",
          serverName: d.serverName,
          reason: d.reason
        });
        return;
      }
      if (kind === "acp_channel_unavailable") {
        res.status(503).json({
          error: errorMessage2(err),
          code: "acp_channel_unavailable"
        });
        return;
      }
      if (kind === "restrictive_sandbox") {
        res.status(403).json({
          error: errorMessage2(err),
          code: "restrictive_sandbox"
        });
        return;
      }
      if (kind === "directory_not_found") {
        const d = data;
        res.status(400).json({
          error: errorMessage2(err),
          code: "directory_not_found",
          path: d.path
        });
        return;
      }
      if (kind === "directory_not_trusted") {
        const d = data;
        res.status(403).json({
          error: errorMessage2(err),
          code: "directory_not_trusted",
          path: d.path
        });
        return;
      }
      if (kind === "invalid_transcript_cursor") {
        res.status(400).json({
          error: errorMessage2(err),
          code: "invalid_transcript_cursor"
        });
        return;
      }
      if (kind === "invalid_transcript_limit") {
        res.status(400).json({
          error: errorMessage2(err),
          code: "invalid_transcript_limit"
        });
        return;
      }
      if (kind === "transcript_snapshot_unavailable") {
        const d = data;
        res.status(409).json({
          error: errorMessage2(err),
          code: "transcript_snapshot_unavailable",
          ...d.sessionId ? { sessionId: d.sessionId } : {}
        });
        return;
      }
      if (kind === "transcript_too_large") {
        const d = data;
        res.status(413).json({
          error: errorMessage2(err),
          code: "transcript_too_large",
          ...d.sessionId ? { sessionId: d.sessionId } : {},
          ...typeof d.snapshotSize === "number" ? { snapshotSize: d.snapshotSize } : {},
          ...typeof d.maxBytes === "number" ? { maxBytes: d.maxBytes } : {}
        });
        return;
      }
    }
  }
  recordDaemonBridgeError(err);
  const extraContext = bridgeErrorExtraContext(ctx);
  recordDaemonError(void 0, err, {
    ...ctx?.route ? { "http.route": ctx.route } : {},
    ...ctx?.sessionId ? { "session.id": ctx.sessionId } : {}
  });
  emitDaemonLog("Daemon bridge error.", {
    ...ctx?.route ? { "http.route": ctx.route } : {},
    ...ctx?.sessionId ? { "session.id": ctx.sessionId } : {},
    ...extraContext,
    "error.type": err instanceof Error ? err.name : typeof err,
    "error.message": (err instanceof Error ? err.message : String(err)).slice(
      0,
      1024
    )
  });
  if (daemonLog) {
    daemonLog.error(
      err instanceof Error ? err.message : String(err),
      err instanceof Error ? err : void 0,
      {
        ...ctx?.route ? { route: ctx.route } : {},
        ...ctx?.sessionId ? { sessionId: ctx.sessionId } : {},
        ...extraContext
      }
    );
  } else {
    const ctxParts = [
      ctx?.route,
      ctx?.sessionId ? `session=${ctx.sessionId}` : void 0,
      ...Object.entries(extraContext).map(([key, value]) => `${key}=${value}`)
    ].filter(Boolean);
    const ctxStr = ctxParts.length > 0 ? ` (${ctxParts.join(" ")})` : "";
    writeStderrLine(
      `qwen serve: bridge error${ctxStr}: ${err instanceof Error ? err.stack ?? err.message : String(err)}`
    );
  }
  res.status(500).json(errorPayload(err));
}
__name(sendBridgeError, "sendBridgeError");
function errorMessage2(err) {
  if (err instanceof Error) return err.message;
  if (err && typeof err === "object") {
    const maybe = err.message;
    if (typeof maybe === "string" && maybe.length > 0) return maybe;
    try {
      return JSON.stringify(err);
    } catch {
    }
  }
  return String(err);
}
__name(errorMessage2, "errorMessage");
function errorPayload(err) {
  const out = {
    error: errorMessage2(err)
  };
  if (err && typeof err === "object") {
    const obj = err;
    if ("code" in obj) out.code = obj["code"];
    if ("data" in obj) out.data = obj["data"];
  }
  return out;
}
__name(errorPayload, "errorPayload");

// packages/cli/src/serve/routes/sse-events.ts
var activeSseCount = 0;
function getActiveSseCount() {
  return activeSseCount;
}
__name(getActiveSseCount, "getActiveSseCount");
function formatSseFrame(event) {
  const existingMeta = event._meta;
  const existingServerTimestamp = existingMeta?.["serverTimestamp"];
  const serverTimestamp = typeof existingServerTimestamp === "number" && Number.isFinite(existingServerTimestamp) ? existingServerTimestamp : Date.now();
  const stamped = {
    ...event,
    _meta: { ...existingMeta ?? {}, serverTimestamp }
  };
  const dataJson = JSON.stringify(stamped);
  const idLine = "id" in event && event.id !== void 0 ? `id: ${event.id}
` : "";
  return `${idLine}event: ${event.type}
data: ${dataJson}

`;
}
__name(formatSseFrame, "formatSseFrame");
function registerSseEventsRoutes(app, deps) {
  const { workspaceRegistry, daemonLog, sendBridgeError: sendBridgeError2, writerIdleTimeoutMs } = deps;
  app.get("/session/:id/events", (req, res) => {
    const sessionId = req.params["id"];
    const lastEventId = parseLastEventId(req.headers["last-event-id"]);
    const maxQueued = parseMaxQueuedQuery(req.query["maxQueued"], res);
    if (maxQueued === null) return;
    let iter;
    const abort = new AbortController();
    try {
      const runtime = requireSessionRuntime({
        sessionId,
        route: "GET /session/:id/events",
        res,
        workspaceRegistry,
        daemonLog
      });
      if (!runtime) return;
      const snapshot = req.query["snapshot"] === "1";
      const iterable = runtime.bridge.subscribeEvents(sessionId, {
        signal: abort.signal,
        lastEventId,
        ...maxQueued !== void 0 ? { maxQueued } : {},
        ...snapshot ? { snapshot: true } : {}
      });
      iter = iterable[Symbol.asyncIterator]();
    } catch (err) {
      if (err instanceof SubscriberLimitExceededError) {
        writeStderrLine(
          `qwen serve: subscriber limit reached for session ${sessionId} (limit=${err.limit}); rejecting new SSE client with 429`
        );
        res.setHeader("Retry-After", "5");
        res.status(429).json({
          error: err.message,
          code: "subscriber_limit_exceeded",
          limit: err.limit
        });
        return;
      }
      sendBridgeError2(res, err, {
        route: "GET /session/:id/events",
        sessionId
      });
      return;
    }
    if (daemonLog) {
      const sseOpenedAt = Date.now();
      const sseClientId = req.headers["x-qwen-client-id"];
      daemonLog.info("SSE stream opened", { sessionId, clientId: sseClientId });
      res.on("close", () => {
        try {
          daemonLog.info("SSE stream closed", {
            sessionId,
            clientId: sseClientId,
            durationMs: Date.now() - sseOpenedAt
          });
        } catch {
        }
      });
    }
    res.status(200);
    res.setHeader("Content-Type", "text/event-stream");
    res.setHeader("Cache-Control", "no-cache, no-transform");
    res.setHeader("Connection", "keep-alive");
    res.setHeader("X-Accel-Buffering", "no");
    res.flushHeaders();
    activeSseCount++;
    let sseCounted = true;
    res.on("close", () => {
      if (sseCounted) {
        sseCounted = false;
        activeSseCount--;
      }
    });
    let writeChain = Promise.resolve();
    const trackWriterIdle = writerIdleTimeoutMs !== void 0 && writerIdleTimeoutMs > 0;
    let lastWriteAt = trackWriterIdle ? Date.now() : 0;
    const doWrite = /* @__PURE__ */ __name((chunk) => new Promise((resolve5, reject) => {
      if (res.writableEnded) {
        resolve5();
        return;
      }
      let ok;
      try {
        ok = res.write(chunk);
      } catch (err) {
        reject(err);
        return;
      }
      if (ok) {
        if (trackWriterIdle) lastWriteAt = Date.now();
        resolve5();
        return;
      }
      const onDrain = /* @__PURE__ */ __name(() => {
        res.off("close", onClose);
        res.off("error", onError);
        if (trackWriterIdle) lastWriteAt = Date.now();
        resolve5();
      }, "onDrain");
      const onClose = /* @__PURE__ */ __name(() => {
        res.off("drain", onDrain);
        res.off("error", onError);
        resolve5();
      }, "onClose");
      const onError = /* @__PURE__ */ __name((err) => {
        res.off("drain", onDrain);
        res.off("close", onClose);
        reject(err);
      }, "onError");
      res.once("drain", onDrain);
      res.once("close", onClose);
      res.once("error", onError);
    }), "doWrite");
    const writeWithBackpressure = /* @__PURE__ */ __name((chunk) => {
      const next = writeChain.then(() => doWrite(chunk));
      writeChain = next.catch(() => void 0);
      return next;
    }, "writeWithBackpressure");
    void writeWithBackpressure("retry: 3000\n\n").catch(() => {
    });
    const heartbeatTimer = setInterval(() => {
      if (!res.writableEnded) {
        void writeWithBackpressure(": heartbeat\n\n").catch(() => {
        });
      }
    }, 15e3);
    heartbeatTimer.unref();
    let idleTimer;
    const cleanup = /* @__PURE__ */ __name(() => {
      clearInterval(heartbeatTimer);
      if (idleTimer !== void 0) clearInterval(idleTimer);
      abort.abort();
    }, "cleanup");
    if (trackWriterIdle) {
      const writerIdleTimeoutMsValue = writerIdleTimeoutMs;
      const checkIntervalMs = Math.max(
        250,
        Math.min(5e3, Math.floor(writerIdleTimeoutMsValue / 4))
      );
      idleTimer = setInterval(() => {
        if (res.writableEnded) return;
        const idleForMs = Date.now() - lastWriteAt;
        if (idleForMs < writerIdleTimeoutMsValue) return;
        try {
          res.write(
            formatSseFrame({
              v: 1,
              type: "client_evicted",
              data: {
                reason: "writer_idle_timeout",
                errorKind: "writer_idle_timeout",
                idleForMs,
                timeoutMs: writerIdleTimeoutMsValue
              }
            })
          );
        } catch {
        }
        try {
          writeStderrLine(
            `qwen serve: evicting SSE client (session ${sessionId}) \u2014 writer idle for ${idleForMs}ms > ${writerIdleTimeoutMsValue}ms timeout`
          );
        } catch {
        }
        cleanup();
        try {
          if (!res.writableEnded) res.end();
        } catch {
        }
      }, checkIntervalMs);
      idleTimer.unref();
    }
    req.on("close", cleanup);
    res.on("error", (err) => {
      writeStderrLine(
        `qwen serve: SSE socket error (session ${sessionId}): ${err.message}`
      );
      cleanup();
    });
    void (async () => {
      try {
        while (true) {
          const next = await iter.next();
          if (next.done) break;
          if (res.writableEnded) break;
          if (next.value.type === "state_resync_required") {
            const data = next.value.data;
            const gap = typeof data.earliestAvailableId === "number" && typeof data.lastDeliveredId === "number" ? data.earliestAvailableId - data.lastDeliveredId - 1 : void 0;
            writeStderrLine(
              `qwen serve: SSE ring eviction detected (session ${sessionId}): lastEventId=${data.lastDeliveredId ?? "?"}, earliestInRing=${data.earliestAvailableId ?? "?"}, gap=${gap ?? "?"} events, reason=${data.reason ?? "?"}. Consumer must call loadSession to recover.`
            );
          }
          await writeWithBackpressure(formatSseFrame(next.value));
        }
      } catch (err) {
        if (!res.writableEnded) {
          const errorKind = mapDomainErrorToErrorKind(err);
          writeStderrLine(
            `qwen serve: bridge iterator error (session ${sessionId}): ${errorMessage2(err)}` + (errorKind ? ` [${errorKind}]` : "")
          );
          await writeWithBackpressure(
            formatSseFrame({
              v: 1,
              type: "stream_error",
              data: {
                error: errorMessage2(err),
                ...errorKind ? { errorKind } : {}
              }
            })
          ).catch(() => {
          });
        }
      } finally {
        cleanup();
        if (!res.writableEnded) res.end();
      }
    })();
  });
}
__name(registerSseEventsRoutes, "registerSseEventsRoutes");

// packages/cli/src/serve/routes/workspace-models.ts
init_esbuild_shims();

// packages/cli/src/serve/model-providers-edit.ts
init_esbuild_shims();
function removeModelFromProviders(modelProviders, providerProtocol, target) {
  let idOnly;
  for (const [key, models] of Object.entries(modelProviders)) {
    if (!Array.isArray(models)) continue;
    const protocol = resolveProviderProtocol(key, providerProtocol) ?? key;
    if (protocol !== target.authType) continue;
    for (let index = 0; index < models.length; index++) {
      if (models[index].id !== target.modelId) continue;
      if (target.baseUrl === void 0 || (models[index].baseUrl ?? void 0) === target.baseUrl) {
        return buildRemoval(modelProviders, key, index);
      }
      if (!idOnly) idOnly = { key, index };
    }
  }
  if (idOnly) return buildRemoval(modelProviders, idOnly.key, idOnly.index);
  return { next: modelProviders, removed: false };
}
__name(removeModelFromProviders, "removeModelFromProviders");
function buildRemoval(modelProviders, key, index) {
  const models = modelProviders[key] ?? [];
  const removedBaseUrl = models[index]?.baseUrl;
  const nextModels = models.filter((_, i) => i !== index);
  const next = { ...modelProviders };
  next[key] = nextModels;
  return {
    next,
    removed: true,
    ...removedBaseUrl ? { removedBaseUrl } : {}
  };
}
__name(buildRemoval, "buildRemoval");
function isActiveModelSelection(activeModelName, activeBaseUrl, target) {
  if (!activeModelName || activeModelName !== target.modelId) return false;
  if (!activeBaseUrl) return true;
  if (!target.baseUrl) return false;
  return activeBaseUrl === target.baseUrl;
}
__name(isActiveModelSelection, "isActiveModelSelection");

// packages/cli/src/serve/routes/workspace-models.ts
var MAX_MODEL_FIELD_LENGTH = 1024;
function scopeToWire(scope) {
  if (scope === "Workspace" /* Workspace */) return "workspace";
  if (scope === "User" /* User */) return "user";
  throw new Error(`unexpected settings scope for wire mapping: ${scope}`);
}
__name(scopeToWire, "scopeToWire");
function parseTarget(body) {
  const authType = body["authType"];
  const modelId = body["modelId"];
  const baseUrl = body["baseUrl"];
  if (typeof authType !== "string" || !authType.trim()) {
    return { error: "`authType` is required", code: "invalid_auth_type" };
  }
  if (typeof modelId !== "string" || !modelId.trim()) {
    return { error: "`modelId` is required", code: "invalid_model_id" };
  }
  if (baseUrl !== void 0 && typeof baseUrl !== "string") {
    return { error: "`baseUrl` must be a string", code: "invalid_base_url" };
  }
  if (typeof baseUrl === "string" && baseUrl.length > MAX_MODEL_FIELD_LENGTH) {
    return {
      error: "`baseUrl` exceeds length limit",
      code: "invalid_base_url"
    };
  }
  if (authType.length > MAX_MODEL_FIELD_LENGTH || modelId.length > MAX_MODEL_FIELD_LENGTH) {
    return { error: "field exceeds length limit", code: "invalid_field" };
  }
  const trimmedBaseUrl = typeof baseUrl === "string" ? baseUrl.trim() : "";
  return {
    authType: authType.trim(),
    modelId: modelId.trim(),
    ...trimmedBaseUrl ? { baseUrl: trimmedBaseUrl } : {}
  };
}
__name(parseTarget, "parseTarget");
function registerWorkspaceModelsRoutes(app, deps) {
  const {
    boundWorkspace,
    mutate,
    safeBody: safeBody2,
    persistSettings,
    broadcastSettingsChanged,
    parseAndValidateClientId
  } = deps;
  app.delete(
    "/workspace/models",
    mutate({ strict: true }),
    async (req, res) => {
      const parsed = parseTarget(safeBody2(req));
      if ("error" in parsed) {
        res.status(400).json({ error: parsed.error, code: parsed.code });
        return;
      }
      const clientId = parseAndValidateClientId(req, res);
      if (clientId === null) return;
      const broadcastWrite = /* @__PURE__ */ __name((write) => {
        try {
          broadcastSettingsChanged(
            write.key,
            write.value,
            scopeToWire(write.scope),
            clientId
          );
        } catch (err) {
          writeStderrLine(
            `qwen serve: DELETE /workspace/models broadcast error (key=${write.key}): ${err instanceof Error ? err.message : String(err)}`
          );
        }
      }, "broadcastWrite");
      let writes;
      try {
        const loaded = loadSettings(boundWorkspace);
        const scope = getModelProvidersOwnerScope(loaded) ?? "User" /* User */;
        const modelProviders = loaded.forScope(scope).settings.modelProviders ?? {};
        const { next, removed, removedBaseUrl } = removeModelFromProviders(
          modelProviders,
          loaded.merged.providerProtocol,
          parsed
        );
        if (!removed) {
          res.status(404).json({
            error: "Model not found in configured providers",
            code: "model_not_found"
          });
          return;
        }
        writes = [{ scope, key: "modelProviders", value: next }];
        const activeTarget = {
          authType: parsed.authType,
          modelId: parsed.modelId,
          ...removedBaseUrl ? { baseUrl: removedBaseUrl } : {}
        };
        for (const activeScope of getWritableScopes(loaded)) {
          const scopeModel = loaded.forScope(activeScope).settings.model;
          if (isActiveModelSelection(
            scopeModel?.name,
            scopeModel?.baseUrl,
            activeTarget
          )) {
            writes.push({ scope: activeScope, key: "model.name", value: "" });
            writes.push({
              scope: activeScope,
              key: "model.baseUrl",
              value: ""
            });
          }
        }
        const stillConfigured = Object.values(next).some(
          (models) => Array.isArray(models) && models.some((model) => model.id === parsed.modelId)
        );
        const fallbacksScope = getOwnKeyScope(loaded, "modelFallbacks");
        const fallbacks = fallbacksScope ? loaded.forScope(fallbacksScope).settings.modelFallbacks : void 0;
        if (!stillConfigured && fallbacksScope && typeof fallbacks === "string" && fallbacks.length > 0) {
          const original = fallbacks.split(",").map((entry) => entry.trim()).filter(Boolean);
          const kept = original.filter((id) => id !== parsed.modelId);
          if (kept.length !== original.length) {
            writes.push({
              scope: fallbacksScope,
              key: "modelFallbacks",
              value: kept.join(",")
            });
          }
        }
        try {
          await persistSettings(boundWorkspace, writes);
        } catch (err) {
          if (err instanceof WorkspaceSettingsPartialPersistError) {
            for (const write of err.committedWrites) broadcastWrite(write);
          }
          throw err;
        }
      } catch (err) {
        writeStderrLine(
          `qwen serve: DELETE /workspace/models error (authType=${parsed.authType}, modelId=${parsed.modelId}): ${err instanceof Error ? err.message : String(err)}`
        );
        if (err instanceof WorkspaceSettingsPartialPersistError) {
          res.status(500).json({
            error: "Model removal only partially persisted",
            code: "partial_persist_error",
            committedKeys: err.committedWrites.map((write) => write.key)
          });
          return;
        }
        res.status(500).json({
          error: "Failed to remove model",
          code: "internal_error"
        });
        return;
      }
      for (const write of writes) broadcastWrite(write);
      const clearedActiveModel = writes.some((w) => w.key === "model.name");
      const requiresRestart = writes.some(
        (w) => getSettingDefinition(w.key)?.requiresRestart === true
      );
      res.status(200).json({ removed: true, clearedActiveModel, requiresRestart });
    }
  );
}
__name(registerWorkspaceModelsRoutes, "registerWorkspaceModelsRoutes");

// packages/cli/src/serve/routes/a2ui-action.ts
init_esbuild_shims();
import * as fsp4 from "node:fs/promises";
import * as path13 from "node:path";
var A2UI_MIME = "application/a2ui+json";
var ACTION_TOOL = "action";
var CALL_TIMEOUT_MS = 15e3;
var SCRUBBED_STDIO_ENV_KEYS = /* @__PURE__ */ new Set([
  QWEN_SERVER_TOKEN_ENV
]);
function usableServerConfig(cfg) {
  if (!cfg) return false;
  if (typeof cfg.httpUrl === "string") {
    try {
      const parsed = new URL(cfg.httpUrl);
      return parsed.protocol === "http:" || parsed.protocol === "https:";
    } catch {
      return false;
    }
  }
  return typeof cfg.command === "string" && cfg.command.trim().length > 0;
}
__name(usableServerConfig, "usableServerConfig");
async function findFromSettingsFile(workspaceCwd) {
  try {
    const raw = await fsp4.readFile(
      path13.join(workspaceCwd, ".qwen", "settings.json"),
      "utf8"
    );
    const settings = JSON.parse(raw);
    for (const [name, cfg] of Object.entries(settings.mcpServers ?? {})) {
      if (name.toLowerCase().includes("a2ui") && usableServerConfig(cfg)) {
        return cfg;
      }
    }
  } catch {
  }
  return null;
}
__name(findFromSettingsFile, "findFromSettingsFile");
function buildTransport(cfg, baseEnv = snapshotProcessEnv()) {
  if (typeof cfg.httpUrl === "string") {
    return new StreamableHTTPClientTransport(new URL(cfg.httpUrl));
  }
  return new StdioClientTransport({
    command: cfg.command,
    args: cfg.args ?? [],
    // Passing `env` prevents the SDK from reading live process.env while
    // keeping daemon MCP stdio behavior aligned with the core CLI client.
    env: buildStdioServerEnv(baseEnv, cfg.env),
    cwd: cfg.cwd
  });
}
__name(buildTransport, "buildTransport");
function buildStdioServerEnv(baseEnv, serverEnv) {
  const env = {};
  for (const [key, value] of Object.entries(baseEnv)) {
    if (value !== void 0 && !key.startsWith("BASH_FUNC_") && !value.startsWith("()") && !SCRUBBED_STDIO_ENV_KEYS.has(key)) {
      env[key] = value;
    }
  }
  const merged = { ...env, ...serverEnv ?? {} };
  for (const key of SCRUBBED_STDIO_ENV_KEYS) {
    delete merged[key];
  }
  return merged;
}
__name(buildStdioServerEnv, "buildStdioServerEnv");
function extractA2uiActionResult(result) {
  if (result.isError) {
    const errMsg2 = (result.content ?? []).filter(
      (b) => b.type === "text" && typeof b.text === "string"
    ).map((b) => b.text).join("");
    throw new Error(
      `a2ui action tool returned error: ${errMsg2 || "unknown error"}`
    );
  }
  let commands = null;
  let fallback = "";
  for (const block of result.content ?? []) {
    if (commands === null && block.type === "resource" && block.resource?.mimeType === A2UI_MIME && typeof block.resource.text === "string") {
      try {
        const parsed = JSON.parse(block.resource.text);
        if (Array.isArray(parsed)) commands = parsed;
      } catch {
      }
    } else if (block.type === "text" && typeof block.text === "string") {
      fallback += block.text;
    }
  }
  return { commands, fallback };
}
__name(extractA2uiActionResult, "extractA2uiActionResult");
async function callA2uiAction(cfg, args, env) {
  const transport = buildTransport(cfg, env);
  const client = new Client({ name: "qwen-serve-a2ui", version: "0.0.1" });
  try {
    await client.connect(transport, { timeout: CALL_TIMEOUT_MS });
    const result = await client.callTool(
      { name: ACTION_TOOL, arguments: { ...args } },
      void 0,
      { timeout: CALL_TIMEOUT_MS }
    );
    return extractA2uiActionResult(result);
  } finally {
    await transport.close().catch(() => {
    });
    await client.close().catch(() => {
    });
  }
}
__name(callA2uiAction, "callA2uiAction");
function registerA2uiActionRoutes(app, opts) {
  const { boundWorkspace, mutate, safeBody: safeBody2, getMcpServers } = opts;
  const callAction = opts.callAction ?? ((cfg, args) => callA2uiAction(cfg, args, opts.env));
  app.post(
    "/session/:id/a2ui-action",
    mutate(),
    async (req, res) => {
      const body = safeBody2(req);
      const name = body["name"];
      if (typeof name !== "string" || name.trim().length === 0) {
        res.status(400).json({ error: "`name` is required" });
        return;
      }
      const surfaceId = typeof body["surfaceId"] === "string" ? body["surfaceId"] : void 0;
      const context = body["context"] && typeof body["context"] === "object" && !Array.isArray(body["context"]) ? body["context"] : void 0;
      let cfg = null;
      try {
        const servers = (await getMcpServers()).filter(
          (s) => s.name.toLowerCase().includes("a2ui") && usableServerConfig(s.config)
        );
        const live = servers.find((s) => s.mcpStatus === "connected");
        cfg = (live ?? servers[0])?.config ?? null;
      } catch {
      }
      if (!cfg) cfg = await findFromSettingsFile(boundWorkspace);
      if (!cfg) {
        res.status(503).json({
          error: "no a2ui MCP server found (neither runtime-registered nor in workspace settings mcpServers)"
        });
        return;
      }
      try {
        const { commands, fallback } = await callAction(cfg, {
          name: name.trim(),
          surfaceId,
          context
        });
        res.status(200).json({ commands, fallback });
      } catch (err) {
        writeStderrLine(
          `a2ui-action proxy failed: ${err instanceof Error ? err.message : String(err)}`
        );
        res.status(502).json({ error: "a2ui action call failed" });
      }
    }
  );
}
__name(registerA2uiActionRoutes, "registerA2uiActionRoutes");

// packages/cli/src/serve/server/fs-factory.ts
init_esbuild_shims();
import * as path14 from "node:path";
var IDE_WORKSPACE_PATH_ENV_VAR = "QWEN_CODE_IDE_WORKSPACE_PATH";
function createDefaultFsAuditEmit() {
  const WARN_EVERY = 100;
  let droppedCount = 0;
  return (event) => {
    droppedCount += 1;
    if (droppedCount === 1 || droppedCount % WARN_EVERY === 0) {
      const data = event.data;
      const ctx = [];
      if (data?.errorKind) ctx.push(`errorKind=${data.errorKind}`);
      if (data?.intent) ctx.push(`intent=${data.intent}`);
      if (data?.pathHash) ctx.push(`pathHash=${data.pathHash}`);
      const ctxStr = ctx.length > 0 ? ` (${ctx.join(" ")})` : "";
      writeStderrLine(
        `qwen serve: fs audit emit is the default no-op \u2014 ${droppedCount} event(s) dropped so far. Latest type=${event.type}${ctxStr}. Inject deps.fsFactory in createServeApp to wire audit into the EventBus.`
      );
    }
  };
}
__name(createDefaultFsAuditEmit, "createDefaultFsAuditEmit");
function resolveBridgeFsFactory(input) {
  if (input.injected) return input.injected;
  return createWorkspaceFileSystemFactory({
    boundWorkspaces: input.boundWorkspaces,
    trusted: input.trusted,
    emit: input.emit ?? createDefaultFsAuditEmit(),
    pathLocks: input.pathLocks,
    ...input.customIgnoreFiles !== void 0 ? { customIgnoreFiles: input.customIgnoreFiles } : {}
  });
}
__name(resolveBridgeFsFactory, "resolveBridgeFsFactory");
function resolveBoundWorkspacesFromIdeEnv(primaryWorkspace, ideWorkspacePath = process.env[IDE_WORKSPACE_PATH_ENV_VAR], includeWorkspace) {
  let primary = primaryWorkspace;
  const envCanonicals = [];
  try {
    primary = canonicalizeWorkspace(primaryWorkspace);
  } catch (err) {
    writeStderrLine(
      `qwen serve: failed to canonicalize IDE workspace paths, using primary only: ${err}`
    );
    return [primary];
  }
  for (const workspace of parseIdeWorkspacePathEnv(ideWorkspacePath)) {
    try {
      const canonical = canonicalizeWorkspace(workspace);
      if (envCanonicals.includes(canonical)) continue;
      envCanonicals.push(canonical);
    } catch (err) {
      writeStderrLine(
        `qwen serve: skipping IDE workspace root that failed to canonicalize: ${workspace} (${err})`
      );
    }
  }
  if (envCanonicals.length > 0 && !envCanonicals.some(
    (workspace) => isWithinRoot2(primary, workspace) || isWithinRoot2(workspace, primary)
  )) {
    writeStderrLine(
      "qwen serve: ignoring stale IDE workspace paths that do not overlap the selected workspace"
    );
    return [primary];
  }
  const workspaces = [primary, ...envCanonicals.filter((w) => w !== primary)];
  const filteredWorkspaces = includeWorkspace === void 0 ? workspaces : workspaces.filter(includeWorkspace);
  return dropNestedWorkspacesPreservingPrimary(filteredWorkspaces);
}
__name(resolveBoundWorkspacesFromIdeEnv, "resolveBoundWorkspacesFromIdeEnv");
function parseIdeWorkspacePathEnv(value) {
  if (value === void 0 || value.length === 0) return [];
  if (value.trimStart().startsWith("[")) {
    try {
      const parsed = JSON.parse(value);
      if (Array.isArray(parsed) && parsed.every((item) => typeof item === "string")) {
        return parsed.filter(
          (workspace) => workspace.length > 0 && path14.isAbsolute(workspace)
        );
      }
      throw new Error("IDE workspace path JSON must be a string array");
    } catch {
    }
  }
  return value.split(path14.delimiter).filter((workspace) => workspace.length > 0 && path14.isAbsolute(workspace));
}
__name(parseIdeWorkspacePathEnv, "parseIdeWorkspacePathEnv");
function dropNestedWorkspacesPreservingPrimary(workspaces) {
  const primary = workspaces[0];
  if (primary === void 0) return [];
  const withoutPrimaryOverlaps = workspaces.filter(
    (workspace, i) => i === 0 || workspace !== primary && !isWithinRoot2(workspace, primary) && !isWithinRoot2(primary, workspace)
  );
  const filtered = withoutPrimaryOverlaps.filter(
    (workspace, i) => i === 0 || !withoutPrimaryOverlaps.some(
      (other, j) => i !== j && j !== 0 && workspace !== other && isWithinRoot2(workspace, other)
    )
  );
  if (filtered.length < workspaces.length) {
    writeStderrLine(
      "qwen serve: dropping nested IDE workspace roots (parent folders already cover children)"
    );
  }
  return filtered;
}
__name(dropNestedWorkspacesPreservingPrimary, "dropNestedWorkspacesPreservingPrimary");

// packages/cli/src/serve/server/telemetry.ts
init_esbuild_shims();
function decodePathSegment(value) {
  try {
    return decodeURIComponent(value);
  } catch {
    return value;
  }
}
__name(decodePathSegment, "decodePathSegment");
function resolveDaemonTelemetryRoute(req) {
  const path15 = req.path.replace(/\/$/, "") || "/";
  if (req.method === "POST" && path15 === "/session") {
    return { route: "POST /session" };
  }
  if (req.method === "POST" && path15 === "/sessions/delete") {
    return { route: "POST /sessions/delete" };
  }
  if (req.method === "GET" && path15 === "/daemon/status") {
    return { route: "GET /daemon/status" };
  }
  const rewindSnapshots = path15.match(/^\/session\/([^/]+)\/rewind\/snapshots$/);
  if (rewindSnapshots?.[1] && req.method === "GET") {
    return {
      route: "GET /session/:id/rewind/snapshots",
      sessionId: rewindSnapshots[1]
    };
  }
  const sessionAction = path15.match(
    /^\/session\/([^/]+)\/(load|resume|prompt|cancel|recap|btw|mid-turn-message|model|shell|detach|rewind|approval-mode|language|a2ui-action)$/
  );
  const sessionActionId = sessionAction?.[1];
  const sessionActionName = sessionAction?.[2];
  if (sessionActionId && sessionActionName && req.method === "POST") {
    return {
      route: `POST /session/:id/${sessionActionName}`,
      sessionId: sessionActionId
    };
  }
  const sessionMetadata = path15.match(/^\/session\/([^/]+)\/metadata$/);
  if (sessionMetadata?.[1] && req.method === "PATCH") {
    return {
      route: "PATCH /session/:id/metadata",
      sessionId: sessionMetadata[1]
    };
  }
  const sessionArtifacts = path15.match(/^\/session\/([^/]+)\/artifacts$/);
  if (sessionArtifacts?.[1]) {
    if (req.method === "GET") {
      return {
        route: "GET /session/:id/artifacts",
        sessionId: sessionArtifacts[1]
      };
    }
    if (req.method === "POST") {
      return {
        route: "POST /session/:id/artifacts",
        sessionId: sessionArtifacts[1]
      };
    }
  }
  const sessionArtifact = path15.match(
    /^\/session\/([^/]+)\/artifacts\/([^/]+)$/
  );
  if (sessionArtifact?.[1] && req.method === "DELETE") {
    return {
      route: "DELETE /session/:id/artifacts/:artifactId",
      sessionId: sessionArtifact[1]
    };
  }
  const sessionPermission = path15.match(
    /^\/session\/([^/]+)\/permission\/([^/]+)$/
  );
  if (sessionPermission?.[1] && sessionPermission?.[2] && req.method === "POST") {
    const rawRequestId = sessionPermission[2];
    return {
      route: "POST /session/:id/permission/:requestId",
      sessionId: sessionPermission[1],
      ...rawRequestId.length <= MAX_CLIENT_ID_LENGTH && CLIENT_ID_RE.test(rawRequestId) ? { permissionRequestId: rawRequestId } : {}
    };
  }
  const globalPermission = path15.match(/^\/permission\/([^/]+)$/);
  if (globalPermission?.[1] && req.method === "POST") {
    const rawRequestId = globalPermission[1];
    return {
      route: "POST /permission/:requestId",
      ...rawRequestId.length <= MAX_CLIENT_ID_LENGTH && CLIENT_ID_RE.test(rawRequestId) ? { permissionRequestId: rawRequestId } : {}
    };
  }
  const deleteSession = path15.match(/^\/session\/([^/]+)$/);
  const deleteSessionId = deleteSession?.[1];
  if (deleteSessionId && req.method === "DELETE") {
    return { route: "DELETE /session/:id", sessionId: deleteSessionId };
  }
  if (req.method === "GET" && /^\/workspace\/[^/]+\/sessions$/.test(path15)) {
    return { route: "GET /workspace/:id/sessions" };
  }
  if (req.method === "GET" && /^\/workspaces\/[^/]+\/sessions$/.test(path15)) {
    return { route: "GET /workspace/:id/sessions" };
  }
  const workspaceTranscript = path15.match(
    /^\/workspaces\/[^/]+\/session\/([^/]+)\/transcript$/
  );
  if (workspaceTranscript?.[1] && req.method === "GET") {
    return {
      route: "GET /workspaces/:workspace/session/:id/transcript",
      sessionId: workspaceTranscript[1]
    };
  }
  const workspaceExport = path15.match(
    /^\/workspaces\/[^/]+\/session\/([^/]+)\/export$/
  );
  if (workspaceExport?.[1] && req.method === "GET") {
    return {
      route: "GET /workspaces/:workspace/session/:id/export",
      sessionId: workspaceExport[1]
    };
  }
  const workspaceArchivedExport = path15.match(
    /^\/workspaces\/[^/]+\/session\/([^/]+)\/archive\/export$/
  );
  if (workspaceArchivedExport?.[1] && req.method === "GET") {
    return {
      route: "GET /workspaces/:workspace/session/:id/archive/export",
      sessionId: workspaceArchivedExport[1]
    };
  }
  const pluralWorkspacePrefix = /^\/workspaces\/[^/]+/;
  if (pluralWorkspacePrefix.test(path15)) {
    const suffix = path15.replace(pluralWorkspacePrefix, "/workspace");
    if (req.method === "GET") {
      if (suffix === "/workspace/mcp" || suffix === "/workspace/skills" || suffix === "/workspace/tools" || suffix === "/workspace/providers" || suffix === "/workspace/env" || suffix === "/workspace/preflight" || suffix === "/workspace/hooks" || suffix === "/workspace/settings" || suffix === "/workspace/voice" || suffix === "/workspace/permissions" || suffix === "/workspace/trust" || suffix === "/workspace/memory" || suffix === "/workspace/agents") {
        return { route: `GET ${suffix}` };
      }
      if (/^\/workspace\/agents\/[^/]+$/.test(suffix)) {
        return { route: "GET /workspace/agents/:agentType" };
      }
      if (suffix === "/workspace/file") return { route: "GET /file" };
      if (suffix === "/workspace/file/bytes") {
        return { route: "GET /file/bytes" };
      }
      if (suffix === "/workspace/stat") return { route: "GET /stat" };
      if (suffix === "/workspace/list") return { route: "GET /list" };
      if (suffix === "/workspace/glob") return { route: "GET /glob" };
      if (/^\/workspace\/mcp\/[^/]+\/tools$/.test(suffix)) {
        return { route: "GET /workspace/mcp/:server/tools" };
      }
      if (/^\/workspace\/mcp\/[^/]+\/resources$/.test(suffix)) {
        return { route: "GET /workspace/mcp/:server/resources" };
      }
    }
    if (req.method === "POST") {
      if (suffix === "/workspace/settings" || suffix === "/workspace/voice" || suffix === "/workspace/voice/transcribe" || suffix === "/workspace/permissions" || suffix === "/workspace/trust/request" || suffix === "/workspace/init" || suffix === "/workspace/reload" || suffix === "/workspace/file/write" || suffix === "/workspace/file/edit" || suffix === "/workspace/mcp/servers" || suffix === "/workspace/memory" || suffix === "/workspace/agents" || suffix === "/workspace/sessions/delete" || suffix === "/workspace/sessions/archive" || suffix === "/workspace/sessions/unarchive" || suffix === "/workspace/session-groups") {
        return { route: `POST ${suffix}` };
      }
      if (/^\/workspace\/tools\/[^/]+\/enable$/.test(suffix)) {
        return { route: "POST /workspace/tools/:name/enable" };
      }
      if (/^\/workspace\/mcp\/[^/]+\/restart$/.test(suffix)) {
        return { route: "POST /workspace/mcp/:server/restart" };
      }
      if (/^\/workspace\/agents\/[^/]+$/.test(suffix)) {
        return { route: "POST /workspace/agents/:agentType" };
      }
      if (/^\/workspace\/mcp\/[^/]+\/(approve|enable|disable|authenticate|clear-auth)$/.test(
        suffix
      )) {
        return {
          route: `POST /workspace/mcp/:server/${suffix.split("/").at(-1)}`
        };
      }
    }
    if (req.method === "DELETE" && /^\/workspace\/mcp\/servers\/[^/]+$/.test(suffix)) {
      return { route: "DELETE /workspace/mcp/servers/:name" };
    }
    if (req.method === "DELETE" && /^\/workspace\/agents\/[^/]+$/.test(suffix)) {
      return { route: "DELETE /workspace/agents/:agentType" };
    }
    if (suffix === "/workspace/session-groups" && req.method === "GET") {
      return { route: "GET /workspace/session-groups" };
    }
    if (/^\/workspace\/session-groups\/[^/]+$/.test(suffix) && req.method === "PATCH") {
      return { route: "PATCH /workspace/session-groups/:groupId" };
    }
    if (/^\/workspace\/session-groups\/[^/]+$/.test(suffix) && req.method === "DELETE") {
      return { route: "DELETE /workspace/session-groups/:groupId" };
    }
  }
  if (req.method === "POST" && path15 === "/workspace/init") {
    return { route: "POST /workspace/init" };
  }
  if (req.method === "POST" && path15 === "/workspace/setup-github") {
    return { route: "POST /workspace/setup-github" };
  }
  if (req.method === "POST" && path15 === "/workspace/reload") {
    return { route: "POST /workspace/reload" };
  }
  const mcpRestart = path15.match(/^\/workspace\/mcp\/([^/]+)\/restart$/);
  if (mcpRestart?.[1] && req.method === "POST") {
    return { route: "POST /workspace/mcp/:server/restart" };
  }
  if (req.method === "POST" && path15 === "/workspace/mcp/servers") {
    return { route: "POST /workspace/mcp/servers" };
  }
  const mcpDelete = path15.match(/^\/workspace\/mcp\/servers\/([^/]+)$/);
  if (mcpDelete?.[1] && req.method === "DELETE") {
    return { route: "DELETE /workspace/mcp/servers/:name" };
  }
  if (req.method === "POST" && path15 === "/workspace/auth/device-flow") {
    return { route: "POST /workspace/auth/device-flow" };
  }
  const deviceFlowDelete = path15.match(
    /^\/workspace\/auth\/device-flow\/([^/]+)$/
  );
  if (deviceFlowDelete?.[1] && req.method === "DELETE") {
    return { route: "DELETE /workspace/auth/device-flow/:id" };
  }
  const toolEnable = path15.match(/^\/workspace\/tools\/([^/]+)\/enable$/);
  if (toolEnable?.[1] && req.method === "POST") {
    return { route: "POST /workspace/tools/:name/enable" };
  }
  if (path15 === "/workspace/settings") {
    if (req.method === "GET") return { route: "GET /workspace/settings" };
    if (req.method === "POST") return { route: "POST /workspace/settings" };
  }
  if (path15 === "/workspace/permissions") {
    if (req.method === "GET") return { route: "GET /workspace/permissions" };
    if (req.method === "POST") return { route: "POST /workspace/permissions" };
  }
  if (path15 === "/workspace/trust") {
    if (req.method === "GET") return { route: "GET /workspace/trust" };
  }
  if (req.method === "POST" && path15 === "/workspace/trust/request") {
    return { route: "POST /workspace/trust/request" };
  }
  if (path15 === "/workspace/voice") {
    if (req.method === "GET") return { route: "GET /workspace/voice" };
    if (req.method === "POST") return { route: "POST /workspace/voice" };
  }
  if (req.method === "POST" && path15 === "/workspace/voice/transcribe") {
    return { route: "POST /workspace/voice/transcribe" };
  }
  return void 0;
}
__name(resolveDaemonTelemetryRoute, "resolveDaemonTelemetryRoute");
function daemonTelemetryMiddleware(resolveWorkspaceCwd, recordRequest, resolveSessionWorkspaceCwd) {
  const workspaceHashByCwd = /* @__PURE__ */ new Map();
  const resolveWorkspaceHash = /* @__PURE__ */ __name((workspaceCwd) => {
    const existing = workspaceHashByCwd.get(workspaceCwd);
    if (existing !== void 0) return existing;
    const workspaceHash = hashDaemonWorkspace(workspaceCwd);
    workspaceHashByCwd.set(workspaceCwd, workspaceHash);
    return workspaceHash;
  }, "resolveWorkspaceHash");
  return (req, res, next) => {
    const route = resolveDaemonTelemetryRoute(req);
    if (!route) {
      next();
      return;
    }
    const resolveOwnerWorkspace = route.route === "GET /session/:id/rewind/snapshots" || route.route === "POST /session/:id/rewind" || route.route === "POST /session/:id/shell";
    const sessionId = route.sessionId ? decodePathSegment(route.sessionId) : void 0;
    const workspaceCwd = (resolveOwnerWorkspace && sessionId ? resolveSessionWorkspaceCwd?.(sessionId) : void 0) ?? resolveWorkspaceCwd(req);
    const workspaceHash = resolveWorkspaceHash(workspaceCwd);
    const rawClientId = req.get(CLIENT_ID_HEADER);
    const clientId = rawClientId !== void 0 && rawClientId !== "" && rawClientId.length <= MAX_CLIENT_ID_LENGTH && CLIENT_ID_RE.test(rawClientId) ? rawClientId : void 0;
    const startMs = Date.now();
    void withDaemonRequestSpan(
      {
        method: req.method,
        route: route.route,
        workspaceHash,
        ...sessionId ? { sessionId } : {},
        ...route.permissionRequestId ? { permissionRequestId: route.permissionRequestId } : {},
        ...clientId ? { clientId } : {}
      },
      async (span) => await new Promise((resolve5, reject) => {
        let done = false;
        const finish = /* @__PURE__ */ __name(() => {
          if (done) return;
          done = true;
          recordDaemonHttpResponse(span, res.statusCode);
          const durationMs = Date.now() - startMs;
          recordDaemonHttpRequest(durationMs, route.route, res.statusCode);
          if (route.route !== "GET /daemon/status") {
            recordRequest?.(durationMs, res.statusCode);
          }
          resolve5();
        }, "finish");
        res.once("finish", finish);
        res.once("close", finish);
        try {
          next();
        } catch (error2) {
          recordDaemonError(span, error2);
          reject(error2);
        }
      })
    ).catch(next);
  };
}
__name(daemonTelemetryMiddleware, "daemonTelemetryMiddleware");

// packages/cli/src/serve/server/access-log.ts
init_esbuild_shims();
var SESSION_ID_RE = /\/session\/([^/]+)/;
function installAccessLogMiddleware(app, daemonLog) {
  if (!daemonLog) return;
  app.use((req, res, next) => {
    const { method, path: reqPath } = req;
    if (method === "GET" && reqPath === "/health" || method === "POST" && reqPath.endsWith("/heartbeat")) {
      return next();
    }
    const startMs = Date.now();
    res.on("finish", () => {
      try {
        const status = res.statusCode;
        if (method === "GET" && reqPath.endsWith("/events") && status === 200) {
          return;
        }
        const durationMs = Date.now() - startMs;
        const sessionMatch = reqPath.match(SESSION_ID_RE);
        const sessionId = sessionMatch?.[1];
        const clientId = req.headers["x-qwen-client-id"];
        const ctx = {
          route: `${method} ${reqPath}`,
          ...sessionId ? { sessionId } : {},
          ...clientId ? { clientId } : {},
          status,
          durationMs
        };
        if (status >= 400) {
          daemonLog.warn("request completed", ctx);
        } else {
          daemonLog.info("request completed", ctx);
        }
      } catch {
      }
    });
    next();
  });
}
__name(installAccessLogMiddleware, "installAccessLogMiddleware");

// packages/cli/src/serve/server/device-flow-registry.ts
init_esbuild_shims();

// packages/cli/src/serve/auth/qwen-device-flow-provider.ts
init_esbuild_shims();
var QWEN_OAUTH_SCOPE = "openid profile email model.completion";
var STDERR_DETAIL_MAX = 2048;
function truncateForStderr(detail) {
  if (detail.length <= STDERR_DETAIL_MAX) return detail;
  const dropped = detail.length - STDERR_DETAIL_MAX;
  return `${detail.slice(0, STDERR_DETAIL_MAX)}\u2026[+${dropped} bytes truncated]`;
}
__name(truncateForStderr, "truncateForStderr");
var QwenOAuthDeviceFlowProvider = class {
  static {
    __name(this, "QwenOAuthDeviceFlowProvider");
  }
  providerId = "qwen-oauth";
  client;
  constructor(client) {
    this.client = client ?? new QwenOAuth2Client();
  }
  async start(opts) {
    const { code_verifier, code_challenge } = generatePKCEPair();
    let auth;
    try {
      auth = await this.client.requestDeviceAuthorization(
        {
          scope: QWEN_OAUTH_SCOPE,
          code_challenge,
          code_challenge_method: "S256"
        },
        { signal: opts.signal }
      );
    } catch (err) {
      const detail = err instanceof Error ? err.message : String(err);
      writeStderrLine(
        `[serve] qwen device-flow start failed (raw): ${truncateForStderr(detail)}`
      );
      throw new UpstreamDeviceFlowError(
        "Qwen IdP device authorization request failed"
      );
    }
    if (opts.signal.aborted) {
      throw new UpstreamDeviceFlowError("device-flow start aborted");
    }
    if (!isDeviceAuthorizationSuccess(auth)) {
      const errorData = auth;
      writeStderrLine(
        truncateForStderr(
          `[serve] qwen device-flow start error envelope (raw): error=${errorData?.error ?? "unknown"} description=${errorData?.error_description ?? "(none)"}`
        )
      );
      throw new UpstreamDeviceFlowError(
        "Qwen IdP rejected the device authorization request"
      );
    }
    return {
      deviceCode: brandSecret(auth.device_code),
      pkceVerifier: brandSecret(code_verifier),
      userCode: auth.user_code,
      verificationUri: auth.verification_uri,
      verificationUriComplete: auth.verification_uri_complete,
      expiresIn: auth.expires_in
      // Qwen IdP doesn't return `interval`; registry falls back to the
      // RFC 8628 default (5s) when this is undefined.
    };
  }
  async poll(state, opts) {
    if (!state.pkceVerifier) {
      return {
        kind: "error",
        errorKind: "invalid_grant",
        hint: "Qwen device-flow requires a PKCE verifier"
      };
    }
    if (opts.signal.aborted) {
      return { kind: "pending" };
    }
    let response;
    try {
      response = await this.client.pollDeviceToken(
        {
          device_code: unsafeRevealSecret(state.deviceCode),
          code_verifier: unsafeRevealSecret(state.pkceVerifier)
        },
        { signal: opts.signal }
      );
    } catch (err) {
      const errorKind = err instanceof QwenOAuthPollError ? mapRfc8628OAuthCode(err.oauthError) : "upstream_error";
      const aborted = opts.signal.aborted;
      if (!aborted) {
        let safeDetail;
        if (err instanceof QwenOAuthPollError) {
          const rawOauthError = err.oauthError ?? "(missing)";
          safeDetail = `oauthError=${sanitizeForStderr(rawOauthError)}`;
        } else if (err instanceof Error) {
          safeDetail = `${sanitizeForStderr(err.name)} (message ${err.message.length} bytes; raw suppressed to avoid echoing device_code/PKCE)`;
        } else {
          safeDetail = `<non-Error throw: ${typeof err}>`;
        }
        writeStderrLine(
          `[serve] qwen device-flow poll failed (errorKind=${errorKind}): ${truncateForStderr(safeDetail)}`
        );
      }
      return {
        kind: "error",
        errorKind,
        hint: errorKind === "upstream_error" ? "unexpected response from identity provider" : `Qwen IdP returned ${errorKind}`
      };
    }
    if (isDeviceTokenSuccess(response)) {
      const tokenData = response;
      const credentials = {
        access_token: tokenData.access_token,
        refresh_token: tokenData.refresh_token ?? void 0,
        token_type: tokenData.token_type,
        resource_url: tokenData.resource_url,
        expiry_date: tokenData.expires_in ? Date.now() + tokenData.expires_in * 1e3 : void 0
      };
      const expiresAt = credentials.expiry_date;
      const client = this.client;
      return {
        kind: "success",
        // `persist({signal})`
        // is now threaded end-to-end. The registry passes its
        // per-entry `cancelController.signal`; we forward it to
        // `cacheQwenCredentials({signal})` which forwards to
        // `fs.writeFile(..., {signal})`. A wedged disk write aborts
        // immediately when `cancel()` / `dispose()` / the
        // 30s `DEVICE_FLOW_PERSIST_TIMEOUT_MS` fires, instead of
        // hanging until the OS-level timeout.
        async persist(persistOpts) {
          await cacheQwenCredentials(credentials, {
            signal: persistOpts.signal
          });
          try {
            client.setCredentials(credentials);
          } catch {
          }
          return { expiresAt };
        }
        // `unpersist` was removed in favor of honoring the IdP's
        // already-completed approval over a microsecond cancel/dispose
        // race.
      };
    }
    if (isDeviceTokenPending(response)) {
      const pending = response;
      return pending.slowDown ? { kind: "slow_down" } : { kind: "pending" };
    }
    return {
      kind: "error",
      errorKind: "upstream_error",
      hint: "unexpected response from identity provider"
    };
  }
};
function mapRfc8628OAuthCode(code) {
  switch (code) {
    case "expired_token":
      return "expired_token";
    case "access_denied":
      return "access_denied";
    case "invalid_grant":
      return "invalid_grant";
    default:
      return "upstream_error";
  }
}
__name(mapRfc8628OAuthCode, "mapRfc8628OAuthCode");

// packages/cli/src/serve/server/device-flow-registry.ts
function createDeviceFlowRegistry(deps) {
  const deviceFlowProviderMap = /* @__PURE__ */ new Map();
  for (const provider of deps.providers ?? []) {
    deviceFlowProviderMap.set(provider.providerId, provider);
  }
  if (!deviceFlowProviderMap.has("qwen-oauth")) {
    deviceFlowProviderMap.set("qwen-oauth", new QwenOAuthDeviceFlowProvider());
  }
  const deviceFlowEventSink = {
    publish(emission, originatorClientId) {
      const bridges = deps.resolveEventBridges ? deps.resolveEventBridges() : [deps.bridge];
      for (const bridge of bridges) {
        try {
          bridge.publishWorkspaceEvent({
            type: `auth_device_flow_${emission.type}`,
            data: emission.data,
            ...originatorClientId ? { originatorClientId } : {}
          });
        } catch (err) {
          const message = err instanceof Error ? err.message : String(err);
          writeStderrLine(
            `[serve] auth.device-flow: event delivery failed error=${JSON.stringify(message)}`
          );
        }
      }
    }
  };
  const deviceFlowRegistry = deps.registry ?? new DeviceFlowRegistry({
    events: deviceFlowEventSink,
    audit: {
      record(line) {
        const id = line.deviceFlowId.slice(0, 8);
        const parts = [
          `[serve] auth.device-flow:`,
          `provider=${line.providerId}`,
          `deviceFlowId=${id}...`,
          line.clientId ? `clientId=${line.clientId}` : "clientId=-",
          `status=${line.status}`
        ];
        if (line.errorKind) parts.push(`errorKind=${line.errorKind}`);
        if (line.expiresInMs !== void 0) {
          parts.push(`expiresInMs=${Math.max(0, line.expiresInMs)}`);
        }
        if (line.hint) {
          const STDERR_HINT_MAX = 1024;
          const hint = line.hint.length > STDERR_HINT_MAX ? `${line.hint.slice(0, STDERR_HINT_MAX)}\u2026[+${line.hint.length - STDERR_HINT_MAX} bytes truncated]` : line.hint;
          parts.push(`hint=${JSON.stringify(hint)}`);
        }
        writeStderrLine(parts.join(" "));
      }
    },
    resolveProvider: /* @__PURE__ */ __name((providerId) => deviceFlowProviderMap.get(providerId), "resolveProvider")
  });
  return {
    deviceFlowRegistry,
    getSupportedDeviceFlowProviders: /* @__PURE__ */ __name(() => Array.from(deviceFlowProviderMap.keys()), "getSupportedDeviceFlowProviders")
  };
}
__name(createDeviceFlowRegistry, "createDeviceFlowRegistry");
function setupDeviceFlowRegistry(deps) {
  const runtime = createDeviceFlowRegistry({
    bridge: deps.bridge,
    registry: deps.registry,
    providers: deps.providers,
    resolveEventBridges: deps.resolveEventBridges
  });
  setDeviceFlowRegistry(deps.app, runtime.deviceFlowRegistry);
  return runtime;
}
__name(setupDeviceFlowRegistry, "setupDeviceFlowRegistry");

// packages/cli/src/serve/server/error-handlers.ts
init_esbuild_shims();
var import_express3 = __toESM(require_express(), 1);
function installJsonBodyParser(app) {
  app.use(import_express3.default.json({ limit: "10mb" }));
  app.use((err, _req, res, next) => {
    if (sendJsonBodyParserError(res, err)) return;
    next(err);
  });
}
__name(installJsonBodyParser, "installJsonBodyParser");
function isMalformedRouteEncoding(err) {
  if (!(err instanceof URIError)) return false;
  const status = err.status;
  const statusCode = err.statusCode;
  return status === 400 || statusCode === 400;
}
__name(isMalformedRouteEncoding, "isMalformedRouteEncoding");
function installFinalErrorHandler(app) {
  app.use((err, _req, res, _next) => {
    if (sendJsonBodyParserError(res, err)) return;
    if (isMalformedRouteEncoding(err)) {
      res.status(400).json({
        error: "Malformed URL encoding",
        code: "invalid_request"
      });
      return;
    }
    writeStderrLine(
      `qwen serve: unhandled error: ${err instanceof Error ? err.stack ?? err.message : String(err)}`
    );
    if (!res.headersSent) {
      res.status(500).json({ error: "Internal server error" });
    }
  });
}
__name(installFinalErrorHandler, "installFinalErrorHandler");

// packages/cli/src/serve/server/rate-limiter-setup.ts
init_esbuild_shims();
function installRateLimiter(app, opts, daemonLog, options = {}) {
  if (!opts.rateLimit) return void 0;
  const windowMs = opts.rateLimitWindowMs ?? 6e4;
  const rateLimiter = createRateLimiter({
    tiers: {
      prompt: { windowMs, max: opts.rateLimitPrompt ?? 10 },
      mutation: { windowMs, max: opts.rateLimitMutation ?? 30 },
      read: { windowMs, max: opts.rateLimitRead ?? 120 }
    },
    hostname: opts.hostname,
    workspaceQualifiedAcpEnabled: options.workspaceQualifiedAcpEnabled === true,
    onLimitReached: daemonLog ? (tier, key, suppressed) => {
      daemonLog.warn(
        `rate limit hit${suppressed > 0 ? ` (${suppressed} suppressed)` : ""}`,
        { tier, key: key.slice(0, 64) }
      );
    } : void 0,
    onError: daemonLog ? (err, path15) => {
      daemonLog.warn(
        `rate limiter error (fail-open): ${err instanceof Error ? err.message : String(err)}`,
        { path: path15 }
      );
    } : void 0
  });
  if (options.mount !== false) {
    app.use(rateLimiter.middleware);
  }
  return rateLimiter;
}
__name(installRateLimiter, "installRateLimiter");

// packages/cli/src/serve/server/self-origin.ts
init_esbuild_shims();
function installSelfOriginStripMiddleware(app, getPort) {
  let cachedStripPort = -1;
  let cachedSelfOrigins = /* @__PURE__ */ new Set();
  app.use((req, _res, next) => {
    const origin = req.headers.origin;
    if (origin) {
      const port = getPort();
      if (port !== cachedStripPort) {
        cachedStripPort = port;
        cachedSelfOrigins = /* @__PURE__ */ new Set([
          `http://127.0.0.1:${port}`,
          `http://localhost:${port}`,
          `http://[::1]:${port}`,
          `http://host.docker.internal:${port}`,
          `https://127.0.0.1:${port}`,
          `https://localhost:${port}`,
          `https://[::1]:${port}`,
          `https://host.docker.internal:${port}`
        ]);
        if (port === 80 || port === 443) {
          for (const host of [
            "127.0.0.1",
            "localhost",
            "[::1]",
            "host.docker.internal"
          ]) {
            cachedSelfOrigins.add(`http://${host}`);
            cachedSelfOrigins.add(`https://${host}`);
          }
        }
      }
      if (cachedSelfOrigins.has(origin)) {
        delete req.headers.origin;
      }
    }
    next();
  });
}
__name(installSelfOriginStripMiddleware, "installSelfOriginStripMiddleware");

// packages/cli/src/serve/routes/workspace-lifecycle.ts
init_esbuild_shims();
function registerWorkspaceLifecycleRoutes(app, deps) {
  const {
    boundWorkspace,
    workspace,
    mutate,
    safeBody: safeBody2,
    sendBridgeError: sendBridgeError2,
    invalidateServeFeaturesCache,
    parseAndValidateClientId
  } = deps;
  const buildWorkspaceCtx = createBuildWorkspaceCtx(boundWorkspace);
  app.post("/workspace/init", mutate({ strict: true }), async (req, res) => {
    const body = safeBody2(req);
    const force = body["force"];
    if (force !== void 0 && typeof force !== "boolean") {
      res.status(400).json({
        error: "`force` must be a boolean when provided",
        code: "invalid_force_flag"
      });
      return;
    }
    const clientId = parseAndValidateClientId(req, res);
    if (clientId === null) return;
    try {
      const ctx = buildWorkspaceCtx("POST /workspace/init", clientId);
      const result = await workspace.initWorkspace(ctx, {
        force: force === true
      });
      res.status(200).json(result);
    } catch (err) {
      sendBridgeError2(res, err, { route: "POST /workspace/init" });
    }
  });
  app.post("/workspace/reload", mutate({ strict: true }), async (req, res) => {
    const clientId = parseAndValidateClientId(req, res);
    if (clientId === null) return;
    try {
      const ctx = buildWorkspaceCtx("POST /workspace/reload", clientId);
      const result = await workspace.reload(ctx);
      invalidateServeFeaturesCache();
      res.status(200).json(result);
    } catch (err) {
      sendBridgeError2(res, err, { route: "POST /workspace/reload" });
    }
  });
}
__name(registerWorkspaceLifecycleRoutes, "registerWorkspaceLifecycleRoutes");
function registerWorkspaceQualifiedLifecycleRoutes(app, deps) {
  app.post(
    "/workspaces/:workspace/init",
    deps.mutate({ strict: true }),
    async (req, res) => {
      const runtime = resolveWorkspaceRuntimeFromParam(
        deps.workspaceRegistry,
        req,
        res
      );
      if (!runtime || !requireTrustedWorkspaceRuntime(runtime, res)) return;
      const body = deps.safeBody(req);
      const force = body["force"];
      if (force !== void 0 && typeof force !== "boolean") {
        res.status(400).json({
          error: "`force` must be a boolean when provided",
          code: "invalid_force_flag"
        });
        return;
      }
      const clientId = parseAndValidateWorkspaceClientId(
        req,
        res,
        runtime.bridge
      );
      if (clientId === null) return;
      const route = "POST /workspaces/:workspace/init";
      try {
        const ctx = createBuildWorkspaceCtx(runtime.workspaceCwd)(
          route,
          clientId
        );
        const result = await runtime.workspaceService.initWorkspace(ctx, {
          force: force === true
        });
        res.status(200).json(result);
      } catch (err) {
        deps.sendBridgeError(res, err, { route });
      }
    }
  );
  app.post(
    "/workspaces/:workspace/reload",
    deps.mutate({ strict: true }),
    async (req, res) => {
      const runtime = resolveWorkspaceRuntimeFromParam(
        deps.workspaceRegistry,
        req,
        res
      );
      if (!runtime || !requireTrustedWorkspaceRuntime(runtime, res)) return;
      const clientId = parseAndValidateWorkspaceClientId(
        req,
        res,
        runtime.bridge
      );
      if (clientId === null) return;
      const route = "POST /workspaces/:workspace/reload";
      try {
        const ctx = createBuildWorkspaceCtx(runtime.workspaceCwd)(
          route,
          clientId
        );
        const result = await runtime.workspaceService.reload(ctx);
        deps.invalidateServeFeaturesCache();
        res.status(200).json(result);
      } catch (err) {
        deps.sendBridgeError(res, err, { route });
      }
    }
  );
}
__name(registerWorkspaceQualifiedLifecycleRoutes, "registerWorkspaceQualifiedLifecycleRoutes");

// packages/cli/src/serve/routes/workspace-management.ts
init_esbuild_shims();
import { stat } from "node:fs/promises";
import { realpathSync } from "node:fs";
import { isAbsolute as isAbsolute7, resolve as resolve4 } from "node:path";
function registerWorkspaceManagementRoutes(app, deps) {
  const {
    workspaceRegistry,
    mutate,
    safeBody: safeBody2,
    createWorkspaceRuntime,
    workspaceRegistrationStore,
    getAcpHandle,
    runtimeRemoval
  } = deps;
  const inFlight = /* @__PURE__ */ new Map();
  let sealed = false;
  let activeOperations = 0;
  const idleWaiters = /* @__PURE__ */ new Set();
  const operationStarted = /* @__PURE__ */ __name(() => {
    activeOperations++;
  }, "operationStarted");
  const operationFinished = /* @__PURE__ */ __name(() => {
    activeOperations--;
    if (activeOperations !== 0) return;
    for (const resolveIdle of idleWaiters) resolveIdle();
    idleWaiters.clear();
  }, "operationFinished");
  const sendSealed = /* @__PURE__ */ __name((res) => {
    res.status(503).json({
      error: "Daemon is shutting down",
      code: "daemon_shutting_down"
    });
  }, "sendSealed");
  app.post(
    "/workspaces",
    mutate({ strict: true }),
    async (req, res) => {
      const body = safeBody2(req);
      const cwd = body["cwd"];
      const persist = body["persist"] ?? false;
      if (typeof cwd !== "string" || cwd.trim().length === 0) {
        res.status(400).json({
          error: "`cwd` must be a non-empty string",
          code: "invalid_path"
        });
        return;
      }
      if (typeof persist !== "boolean") {
        res.status(400).json({
          error: "`persist` must be a boolean",
          code: "invalid_persist_flag"
        });
        return;
      }
      if (persist && !workspaceRegistrationStore) {
        res.status(501).json({
          error: "Persistent workspace registration is not available",
          code: "persistence_not_available"
        });
        return;
      }
      if (!createWorkspaceRuntime && !persist) {
        res.status(501).json({
          error: "Dynamic workspace registration is not available",
          code: "not_implemented"
        });
        return;
      }
      if (!isAbsolute7(cwd)) {
        res.status(400).json({
          error: "`cwd` must be an absolute path",
          code: "invalid_path"
        });
        return;
      }
      if (cwd.length > MAX_WORKSPACE_PATH_LENGTH) {
        res.status(400).json({
          error: `\`cwd\` exceeds the ${MAX_WORKSPACE_PATH_LENGTH}-character limit`,
          code: "invalid_path"
        });
        return;
      }
      let canonical;
      try {
        canonical = realpathSync.native(resolve4(cwd));
      } catch {
        res.status(400).json({
          error: "Path does not exist or is not accessible",
          code: "invalid_path"
        });
        return;
      }
      if (sealed) {
        sendSealed(res);
        return;
      }
      try {
        const s = await stat(canonical);
        if (!s.isDirectory()) {
          res.status(400).json({
            error: "Path is not a directory",
            code: "invalid_path"
          });
          return;
        }
      } catch {
        res.status(400).json({
          error: "Path does not exist or is not accessible",
          code: "invalid_path"
        });
        return;
      }
      if (sealed) {
        sendSealed(res);
        return;
      }
      const activeOperation = inFlight.get(canonical);
      if (activeOperation === "removal") {
        res.status(409).json({
          error: "Workspace removal is in progress",
          code: "workspace_removal_in_progress"
        });
        return;
      }
      const existingRuntime = workspaceRegistry.getManagedByWorkspaceCwd(canonical);
      if (existingRuntime?.primary && persist) {
        res.status(400).json({
          error: "Primary workspace cannot be persisted",
          code: "invalid_persist_target"
        });
        return;
      }
      if (existingRuntime && persist && !existingRuntime.primary) {
        if (activeOperation) {
          res.status(409).json({
            error: "Workspace registration is in progress",
            code: "workspace_registration_in_progress"
          });
          return;
        }
        const nested = [
          ...workspaceRegistry.listManaged().map((runtime) => runtime.workspaceCwd),
          ...[...inFlight].flatMap(
            ([cwd2, operation]) => operation === "addition" || operation === "promotion" ? [cwd2] : []
          )
        ].some(
          (boundCwd) => boundCwd !== canonical && (isWithinRoot(canonical, boundCwd) || isWithinRoot(boundCwd, canonical))
        );
        if (nested) {
          res.status(409).json({
            error: "Workspace path nests with an existing workspace",
            code: "workspace_nested"
          });
          return;
        }
        inFlight.set(canonical, "promotion");
        operationStarted();
        try {
          const snapshot = await workspaceRegistrationStore.read();
          const alreadyPersisted = snapshot.workspaces.some(
            (stored) => existingRuntime.registrationIds?.includes(
              workspaceRegistrationId(stored)
            ) === true || (process.platform === "win32" ? stored.toLowerCase() === canonical.toLowerCase() : stored === canonical)
          );
          if (!alreadyPersisted && snapshot.workspaces.length >= MAX_REGISTERED_WORKSPACES - 1) {
            res.status(409).json({
              error: "Workspace registration limit reached",
              code: "workspace_limit_reached"
            });
            return;
          }
          if (!alreadyPersisted) {
            try {
              await workspaceRegistrationStore.add(canonical);
            } catch (err) {
              if (!(err instanceof WorkspaceRegistrationStoreCommittedError)) {
                throw err;
              }
              try {
                writeStderrLine(`qwen serve: ${err.message}`);
              } catch {
              }
            }
          }
          res.status(200).json({
            id: existingRuntime.workspaceId,
            cwd: existingRuntime.workspaceCwd,
            primary: existingRuntime.primary,
            trusted: existingRuntime.trusted,
            persisted: true
          });
        } catch (err) {
          if (err instanceof WorkspaceRegistrationStoreLimitError) {
            res.status(409).json({
              error: "Workspace registration limit reached",
              code: "workspace_limit_reached"
            });
            return;
          }
          writeStderrLine(
            `qwen serve: failed to persist existing workspace registration: ${err instanceof Error ? err.message : String(err)}`
          );
          res.status(500).json({
            error: "Failed to persist workspace registration",
            code: "workspace_registration_store_error"
          });
        } finally {
          inFlight.delete(canonical);
          operationFinished();
        }
        return;
      }
      if (existingRuntime || activeOperation) {
        res.status(409).json({
          error: "Workspace already registered",
          code: "workspace_exists"
        });
        return;
      }
      if (!createWorkspaceRuntime) {
        res.status(501).json({
          error: "Dynamic workspace registration is not available",
          code: "not_implemented"
        });
        return;
      }
      const boundCwds = [
        ...workspaceRegistry.listManaged().map((r) => r.workspaceCwd),
        ...[...inFlight].flatMap(
          ([cwd2, operation]) => operation === "addition" ? [cwd2] : []
        )
      ];
      for (const existing of boundCwds) {
        if (existing !== canonical && (isWithinRoot(canonical, existing) || isWithinRoot(existing, canonical))) {
          res.status(409).json({
            error: "Workspace path nests with an existing workspace",
            code: "workspace_nested"
          });
          return;
        }
      }
      const projectedWorkspaceCwds = new Set(
        workspaceRegistry.listManaged().map((runtime) => runtime.workspaceCwd)
      );
      for (const [cwd2, operation] of inFlight) {
        if (operation === "addition") projectedWorkspaceCwds.add(cwd2);
      }
      if (projectedWorkspaceCwds.size >= MAX_REGISTERED_WORKSPACES) {
        res.status(409).json({
          error: "Workspace registration limit reached",
          code: "workspace_limit_reached"
        });
        return;
      }
      inFlight.set(canonical, "addition");
      operationStarted();
      let persistenceFailed = false;
      try {
        const runtime = await createWorkspaceRuntime(canonical);
        let persistedRecordAdded = false;
        try {
          if (persist) {
            try {
              try {
                persistedRecordAdded = await workspaceRegistrationStore.add(canonical);
              } catch (err) {
                if (!(err instanceof WorkspaceRegistrationStoreCommittedError)) {
                  throw err;
                }
                persistedRecordAdded = true;
                try {
                  writeStderrLine(`qwen serve: ${err.message}`);
                } catch {
                }
              }
            } catch (err) {
              persistenceFailed = true;
              throw err;
            }
          }
          workspaceRegistry.add(runtime);
          try {
            await runtimeRemoval?.runtimeAdded?.(runtime);
          } catch (err) {
            try {
              writeStderrLine(
                `qwen serve: workspace runtime adapter notification failed after registry add: ${err instanceof Error ? err.message : String(err)}`
              );
            } catch {
            }
          }
        } catch (err) {
          if (persistedRecordAdded) {
            try {
              await workspaceRegistrationStore.removeById(
                workspaceRegistrationId(canonical)
              );
            } catch (rollbackErr) {
              writeStderrLine(
                `qwen serve: failed to roll back workspace persistence after runtime registration failure: ${rollbackErr instanceof Error ? rollbackErr.message : String(rollbackErr)}`
              );
            }
          }
          if (runtimeRemoval) {
            await runtimeRemoval.disposeRuntime(runtime, "workspace_removed").catch(() => {
              try {
                runtime.bridge.killAllSync();
              } catch {
              }
            });
          } else {
            await runtime.bridge.shutdown().catch(() => void 0);
          }
          throw err;
        }
        res.status(201).json({
          id: runtime.workspaceId,
          cwd: runtime.workspaceCwd,
          primary: runtime.primary,
          trusted: runtime.trusted,
          ...persist ? { persisted: true } : {}
        });
      } catch (err) {
        writeStderrLine(
          `qwen serve: POST /workspaces failed for ${canonical}: ${err instanceof Error ? err.message : String(err)}`
        );
        if (persistenceFailed) {
          res.status(500).json({
            error: "Failed to persist workspace registration",
            code: "workspace_registration_store_error"
          });
        } else {
          res.status(500).json({
            error: "Failed to register workspace",
            code: "runtime_creation_failed"
          });
        }
      } finally {
        inFlight.delete(canonical);
        operationFinished();
      }
    }
  );
  const workspaceActivity = /* @__PURE__ */ __name((runtime) => {
    const controllerActivity = runtimeRemoval?.getActivity(runtime) ?? {
      pendingSessionStarts: 0,
      channelWorkers: 0,
      voiceSessions: 0
    };
    const acpActivity = getAcpHandle?.()?.getWorkspaceActivity(
      runtime.workspaceId
    ) ?? { acpConnections: 0, memoryTasks: 0 };
    return {
      pendingSessionStarts: controllerActivity.pendingSessionStarts,
      sessions: runtime.bridge.sessionCount,
      activePrompts: runtime.bridge.activePromptCount,
      acpConnections: acpActivity.acpConnections,
      memoryTasks: acpActivity.memoryTasks,
      channelWorkers: controllerActivity.channelWorkers,
      voiceSessions: controllerActivity.voiceSessions
    };
  }, "workspaceActivity");
  const isBusy = /* @__PURE__ */ __name((activity) => Object.values(activity).some((count) => count > 0), "isBusy");
  const resolveManagedRuntime = /* @__PURE__ */ __name((req, res) => {
    const selector = String(req.params["workspace"] ?? "");
    const byId = workspaceRegistry.getManagedByWorkspaceId(selector);
    if (byId) return byId;
    if (!isPortableAbsolutePath(selector)) {
      res.status(400).json({
        error: "`workspace` must decode to a workspace id or absolute path",
        code: "workspace_mismatch"
      });
      return void 0;
    }
    const runtime = resolveManagedWorkspaceRuntimeByPathSelector(
      workspaceRegistry,
      selector
    );
    if (runtime) return runtime;
    res.status(400).json({
      error: "Workspace mismatch: the requested workspace is not registered with this daemon.",
      code: "workspace_mismatch"
    });
    return void 0;
  }, "resolveManagedRuntime");
  app.delete(
    "/workspaces/:workspace",
    mutate({ strict: true }),
    async (req, res) => {
      const body = safeBody2(req);
      const force = body["force"];
      if (force !== void 0 && typeof force !== "boolean") {
        res.status(400).json({
          error: "`force` must be a boolean when provided",
          code: "invalid_force_flag"
        });
        return;
      }
      if (sealed) {
        sendSealed(res);
        return;
      }
      const runtime = resolveManagedRuntime(req, res);
      if (!runtime) return;
      if (runtime.primary) {
        res.status(409).json({
          error: "The primary workspace cannot be removed at runtime",
          code: "primary_workspace_removal_forbidden"
        });
        return;
      }
      if (runtime.removable !== true) {
        res.status(409).json({
          error: "Startup workspaces cannot be removed at runtime",
          code: "static_workspace_removal_forbidden"
        });
        return;
      }
      if (!runtimeRemoval) {
        res.status(501).json({
          error: "Workspace runtime removal is not available",
          code: "workspace_runtime_removal_unsupported"
        });
        return;
      }
      const operation = inFlight.get(runtime.workspaceCwd);
      if (operation) {
        res.status(409).json({
          error: operation === "removal" ? "Workspace removal is in progress" : "Workspace registration is in progress",
          code: operation === "removal" ? "workspace_removal_in_progress" : "workspace_registration_in_progress"
        });
        return;
      }
      const initialActivity = workspaceActivity(runtime);
      if (force !== true && isBusy(initialActivity)) {
        res.status(409).json({
          error: "Workspace has active runtime resources",
          code: "workspace_busy",
          activity: initialActivity
        });
        return;
      }
      inFlight.set(runtime.workspaceCwd, "removal");
      operationStarted();
      let registryDraining = false;
      let controllerDraining = false;
      let acpDraining = false;
      const rollbackDrain = /* @__PURE__ */ __name(() => {
        if (acpDraining) {
          try {
            getAcpHandle?.()?.cancelWorkspaceDrain(runtime.workspaceId);
          } catch {
          }
          acpDraining = false;
        }
        if (controllerDraining) {
          try {
            runtimeRemoval.cancelDrain(runtime);
          } catch {
          }
          controllerDraining = false;
        }
        if (registryDraining) {
          try {
            workspaceRegistry.cancelDrain(runtime);
          } catch {
          }
          registryDraining = false;
        }
      }, "rollbackDrain");
      const convergeCommittedRemoval = /* @__PURE__ */ __name(async () => {
        const logCleanupFailure = /* @__PURE__ */ __name((message) => {
          try {
            writeStderrLine(message);
          } catch {
          }
        }, "logCleanupFailure");
        try {
          getAcpHandle?.()?.commitWorkspaceRemoval(runtime.workspaceId);
        } catch (err) {
          logCleanupFailure(
            `qwen serve: failed to commit workspace ACP removal: ${err instanceof Error ? err.message : String(err)}`
          );
        }
        await runtimeRemoval.disposeRuntime(runtime, "workspace_removed").catch((err) => {
          logCleanupFailure(
            `qwen serve: workspace runtime cleanup failed: ${err instanceof Error ? err.message : String(err)}`
          );
          try {
            runtime.bridge.killAllSync();
          } catch {
          }
        });
        try {
          getAcpHandle?.()?.disposeWorkspace(runtime.workspaceId);
        } catch (err) {
          logCleanupFailure(
            `qwen serve: failed to dispose workspace ACP mount: ${err instanceof Error ? err.message : String(err)}`
          );
        }
        try {
          runtimeRemoval.completeDrain(runtime);
        } catch (err) {
          logCleanupFailure(
            `qwen serve: failed to complete workspace admission drain: ${err instanceof Error ? err.message : String(err)}`
          );
        }
        try {
          workspaceRegistry.completeDrain(runtime);
        } catch (err) {
          logCleanupFailure(
            `qwen serve: failed to complete workspace registry drain: ${err instanceof Error ? err.message : String(err)}`
          );
        }
        registryDraining = false;
        controllerDraining = false;
        acpDraining = false;
      }, "convergeCommittedRemoval");
      try {
        registryDraining = workspaceRegistry.beginDrain(runtime);
        if (!registryDraining) {
          res.status(409).json({
            error: "Workspace removal is in progress",
            code: "workspace_removal_in_progress"
          });
          return;
        }
        runtimeRemoval.beginDrain(runtime);
        controllerDraining = true;
        getAcpHandle?.()?.beginWorkspaceDrain(runtime.workspaceId);
        acpDraining = true;
        const activity = workspaceActivity(runtime);
        if (force !== true && isBusy(activity)) {
          rollbackDrain();
          res.status(409).json({
            error: "Workspace has active runtime resources",
            code: "workspace_busy",
            activity
          });
          return;
        }
        let persistedRegistrationRemoved = false;
        if (workspaceRegistrationStore) {
          try {
            const registrationIds = /* @__PURE__ */ new Set([
              ...runtime.registrationIds ?? [],
              workspaceRegistrationId(runtime.workspaceCwd)
            ]);
            try {
              persistedRegistrationRemoved = await workspaceRegistrationStore.removeByIds([
                ...registrationIds
              ]) > 0;
            } catch (err) {
              if (!(err instanceof WorkspaceRegistrationStoreCommittedError)) {
                throw err;
              }
              persistedRegistrationRemoved = true;
              try {
                writeStderrLine(`qwen serve: ${err.message}`);
              } catch {
              }
            }
          } catch (err) {
            rollbackDrain();
            writeStderrLine(
              `qwen serve: failed to remove workspace persistence: ${err instanceof Error ? err.message : String(err)}`
            );
            res.status(500).json({
              error: "Failed to persist workspace removal",
              code: "workspace_persist_failed"
            });
            return;
          }
        }
        await convergeCommittedRemoval();
        res.status(200).json({
          removed: true,
          workspaceId: runtime.workspaceId,
          workspaceCwd: runtime.workspaceCwd,
          forced: force === true,
          persistedRegistrationRemoved,
          activity
        });
      } catch (err) {
        rollbackDrain();
        writeStderrLine(
          `qwen serve: DELETE /workspaces/:workspace failed: ${err instanceof Error ? err.message : String(err)}`
        );
        if (!res.headersSent) {
          res.status(500).json({
            error: "Failed to remove workspace runtime",
            code: "workspace_runtime_removal_failed"
          });
        }
      } finally {
        inFlight.delete(runtime.workspaceCwd);
        operationFinished();
      }
    }
  );
  const registrationIsActive = /* @__PURE__ */ __name((registrationId) => workspaceRegistry.listManaged().some((runtime) => {
    if (workspaceRegistrationId(runtime.workspaceCwd) === registrationId) {
      return true;
    }
    return runtime.registrationIds?.includes(registrationId) === true;
  }), "registrationIsActive");
  app.get("/workspace-registrations", async (_req, res) => {
    if (!workspaceRegistrationStore) {
      res.status(501).json({
        error: "Persistent workspace registration is not available",
        code: "persistence_not_available"
      });
      return;
    }
    try {
      const snapshot = await workspaceRegistrationStore.read();
      res.json({
        schemaVersion: snapshot.schemaVersion,
        primaryWorkspace: snapshot.primaryWorkspace,
        entries: snapshot.workspaces.map((cwd) => {
          const runtime = workspaceRegistry.getByWorkspaceCwd(cwd);
          return {
            id: workspaceRegistrationId(cwd),
            cwd,
            active: runtime !== void 0 || registrationIsActive(workspaceRegistrationId(cwd)),
            persisted: true
          };
        })
      });
    } catch (err) {
      writeStderrLine(
        `qwen serve: failed to read workspace registrations: ${err instanceof Error ? err.message : String(err)}`
      );
      res.status(500).json({
        error: "Failed to read workspace registrations",
        code: "workspace_registration_store_error"
      });
    }
  });
  app.delete(
    "/workspace-registrations/:id",
    mutate({ strict: true }),
    async (req, res) => {
      if (!workspaceRegistrationStore) {
        res.status(501).json({
          error: "Persistent workspace registration is not available",
          code: "persistence_not_available"
        });
        return;
      }
      if (sealed) {
        sendSealed(res);
        return;
      }
      operationStarted();
      let operationCwd;
      let ownsInFlight = false;
      try {
        const registrationId = String(req.params["id"]);
        let runtime = workspaceRegistry.listManaged().find(
          (candidate) => workspaceRegistrationId(candidate.workspaceCwd) === registrationId || candidate.registrationIds?.includes(registrationId) === true
        );
        operationCwd = runtime?.workspaceCwd;
        if (!operationCwd) {
          let storedCwd;
          try {
            const snapshot = await workspaceRegistrationStore.read();
            storedCwd = snapshot.workspaces.find(
              (workspace) => workspaceRegistrationId(workspace) === registrationId
            );
          } catch (err) {
            writeStderrLine(
              `qwen serve: failed to read workspace registration before forget: ${err instanceof Error ? err.message : String(err)}`
            );
            res.status(500).json({
              error: "Failed to read workspace registration",
              code: "workspace_registration_store_error"
            });
            return;
          }
          if (storedCwd) {
            try {
              operationCwd = realpathSync.native(resolve4(storedCwd));
            } catch {
              operationCwd = resolve4(storedCwd);
            }
          }
        }
        const operation = operationCwd ? inFlight.get(operationCwd) : void 0;
        if (operation) {
          res.status(409).json({
            error: operation === "removal" ? "Workspace removal is in progress" : "Workspace registration is in progress",
            code: operation === "removal" ? "workspace_removal_in_progress" : "workspace_registration_in_progress"
          });
          return;
        }
        if (operationCwd) {
          inFlight.set(operationCwd, "forget");
          ownsInFlight = true;
        }
        runtime = (operationCwd ? workspaceRegistry.getManagedByWorkspaceCwd(operationCwd) : void 0) ?? runtime;
        const active = registrationIsActive(registrationId);
        let removed;
        try {
          removed = await workspaceRegistrationStore.removeById(registrationId);
        } catch (err) {
          if (!(err instanceof WorkspaceRegistrationStoreCommittedError)) {
            throw err;
          }
          removed = true;
          try {
            writeStderrLine(`qwen serve: ${err.message}`);
          } catch {
          }
        }
        if (!removed) {
          res.status(404).json({
            error: "Workspace registration not found",
            code: "workspace_registration_not_found"
          });
          return;
        }
        res.json({
          removed: true,
          active,
          restartRequired: active && runtime?.removable === true
        });
      } catch (err) {
        writeStderrLine(
          `qwen serve: failed to forget workspace registration: ${err instanceof Error ? err.message : String(err)}`
        );
        res.status(500).json({
          error: "Failed to forget workspace registration",
          code: "workspace_registration_store_error"
        });
      } finally {
        if (ownsInFlight && operationCwd) inFlight.delete(operationCwd);
        operationFinished();
      }
    }
  );
  return {
    async sealAndWait() {
      sealed = true;
      if (activeOperations === 0) return;
      await new Promise((resolveIdle) => idleWaiters.add(resolveIdle));
    }
  };
}
__name(registerWorkspaceManagementRoutes, "registerWorkspaceManagementRoutes");

// packages/cli/src/serve/routes/workspace-git.ts
init_esbuild_shims();
function registerWorkspaceGitRoutes(app, deps) {
  app.get("/workspace/git", async (_req, res) => {
    try {
      res.status(200).json(await deps.gitState.getStatus(deps.boundWorkspace, deps.bridge));
    } catch (err) {
      deps.sendBridgeError(res, err, { route: "GET /workspace/git" });
    }
  });
}
__name(registerWorkspaceGitRoutes, "registerWorkspaceGitRoutes");
function resolveTrustedRuntime2(registry, req, res) {
  const runtime = resolveWorkspaceRuntimeFromParam(registry, req, res);
  if (!runtime) return null;
  return requireTrustedWorkspaceRuntime(runtime, res) ? runtime : null;
}
__name(resolveTrustedRuntime2, "resolveTrustedRuntime");
function registerWorkspaceQualifiedGitRoutes(app, deps) {
  app.get("/workspaces/:workspace/git", async (req, res) => {
    const runtime = resolveTrustedRuntime2(deps.workspaceRegistry, req, res);
    if (!runtime) return;
    const route = "GET /workspaces/:workspace/git";
    try {
      res.status(200).json(
        await deps.gitState.getStatus(runtime.workspaceCwd, runtime.bridge)
      );
    } catch (err) {
      deps.sendBridgeError(res, err, { route });
    }
  });
}
__name(registerWorkspaceQualifiedGitRoutes, "registerWorkspaceQualifiedGitRoutes");

// packages/cli/src/serve/workspace-git-state.ts
init_esbuild_shims();
var WorkspaceGitState = class {
  static {
    __name(this, "WorkspaceGitState");
  }
  entries = /* @__PURE__ */ new Map();
  async getStatus(workspaceCwd, bridge) {
    const entry = await this.getOrCreateEntry(workspaceCwd, bridge);
    return { v: 1, workspaceCwd, branch: entry.branch ?? null };
  }
  dispose() {
    for (const pending of this.entries.values()) {
      void pending.then((entry) => entry.dispose()).catch(() => {
      });
    }
    this.entries.clear();
  }
  disposeWorkspace(workspaceCwd) {
    const pending = this.entries.get(workspaceCwd);
    if (!pending) return;
    this.entries.delete(workspaceCwd);
    void pending.then((entry) => entry.dispose()).catch(() => {
    });
  }
  getOrCreateEntry(workspaceCwd, bridge) {
    const existing = this.entries.get(workspaceCwd);
    if (existing) return existing;
    const pending = this.createEntry(workspaceCwd, bridge).catch((error2) => {
      if (this.entries.get(workspaceCwd) === pending) {
        this.entries.delete(workspaceCwd);
      }
      throw error2;
    });
    this.entries.set(workspaceCwd, pending);
    return pending;
  }
  async createEntry(workspaceCwd, bridge) {
    const entry = {
      branch: await resolveBranchName(workspaceCwd),
      dispose: /* @__PURE__ */ __name(() => {
      }, "dispose")
    };
    const refresh = /* @__PURE__ */ __name(async () => {
      const branch = await resolveBranchName(workspaceCwd);
      if (branch === entry.branch) return;
      entry.branch = branch;
      bridge.publishWorkspaceEvent({
        type: "git_branch_changed",
        data: { workspaceCwd, branch: branch ?? null }
      });
    }, "refresh");
    entry.dispose = await watchRepoBranch(workspaceCwd, () => {
      void refresh().catch(() => {
      });
    });
    return entry;
  }
};

// packages/cli/src/serve/routes/workspace-mcp-control.ts
init_esbuild_shims();
function registerWorkspaceMcpControlRoutes(app, deps) {
  const {
    boundWorkspace,
    bridge,
    workspace,
    mutate,
    safeBody: safeBody2,
    sendBridgeError: sendBridgeError2,
    parseAndValidateClientId
  } = deps;
  const buildWorkspaceCtx = createBuildWorkspaceCtx(boundWorkspace);
  app.post(
    "/workspace/mcp/initialize",
    mutate({ strict: true }),
    async (_req, res) => {
      try {
        const result = await bridge.initializeWorkspaceMcp();
        res.status(202).json(result);
      } catch (err) {
        sendBridgeError2(res, err, { route: "POST /workspace/mcp/initialize" });
      }
    }
  );
  app.post(
    "/workspace/mcp/reload",
    mutate({ strict: true }),
    async (_req, res) => {
      try {
        const result = await bridge.reloadWorkspaceMcp();
        res.status(202).json(result);
      } catch (err) {
        sendBridgeError2(res, err, { route: "POST /workspace/mcp/reload" });
      }
    }
  );
  app.post(
    "/workspace/mcp/:server/restart",
    mutate({ strict: true }),
    async (req, res) => {
      const serverName = req.params["server"];
      if (!serverName || typeof serverName !== "string") {
        res.status(400).json({
          error: "Server name path parameter is required",
          code: "invalid_server_name"
        });
        return;
      }
      if (serverName.length > MAX_SERVER_NAME_LENGTH) {
        res.status(400).json({
          error: `Server name exceeds ${MAX_SERVER_NAME_LENGTH}-character limit`,
          code: "invalid_server_name"
        });
        return;
      }
      const clientId = parseAndValidateClientId(req, res);
      if (clientId === null) return;
      let entryIndex;
      const rawEntryIndex = req.query["entryIndex"];
      if (rawEntryIndex !== void 0 && rawEntryIndex !== "*") {
        const candidate = typeof rawEntryIndex === "string" ? rawEntryIndex : void 0;
        const parsed = candidate !== void 0 ? Number.parseInt(candidate, 10) : NaN;
        if (!Number.isInteger(parsed) || parsed < 0 || String(parsed) !== candidate) {
          res.status(400).json({
            error: '`entryIndex` query parameter must be a non-negative integer or "*"',
            code: "invalid_entry_index"
          });
          return;
        }
        entryIndex = parsed;
      }
      try {
        const ctx = buildWorkspaceCtx(
          "POST /workspace/mcp/:server/restart",
          clientId
        );
        const result = await workspace.restartMcpServer(
          ctx,
          serverName,
          entryIndex !== void 0 ? { entryIndex } : void 0
        );
        res.status(200).json(result);
      } catch (err) {
        sendBridgeError2(res, err, {
          route: "POST /workspace/mcp/:server/restart"
        });
      }
    }
  );
  for (const [routeAction, bridgeAction] of [
    ["approve", "approve"],
    ["enable", "enable"],
    ["disable", "disable"],
    ["authenticate", "authenticate"],
    ["clear-auth", "clear-auth"]
  ]) {
    app.post(
      `/workspace/mcp/:server/${routeAction}`,
      mutate({ strict: true }),
      async (req, res) => {
        const serverName = req.params["server"];
        if (!serverName || typeof serverName !== "string") {
          res.status(400).json({
            error: "Server name path parameter is required",
            code: "invalid_server_name"
          });
          return;
        }
        if (serverName.length > MAX_SERVER_NAME_LENGTH) {
          res.status(400).json({
            error: `Server name exceeds ${MAX_SERVER_NAME_LENGTH}-character limit`,
            code: "invalid_server_name"
          });
          return;
        }
        const clientId = parseAndValidateClientId(req, res);
        if (clientId === null) return;
        try {
          const result = await bridge.manageMcpServer(
            serverName,
            bridgeAction,
            clientId
          );
          res.status(200).json(result);
        } catch (err) {
          sendBridgeError2(res, err, {
            route: `POST /workspace/mcp/:server/${routeAction}`
          });
        }
      }
    );
  }
  app.post(
    "/workspace/mcp/servers",
    mutate({ strict: true }),
    async (req, res) => {
      const body = safeBody2(req);
      const name = body["name"];
      if (!validateMcpRuntimeServerName(name, res)) return;
      const config = body["config"];
      if (typeof config !== "object" || config === null || Array.isArray(config)) {
        res.status(400).json({
          error: "`config` must be a non-null object",
          code: "missing_required_field",
          field: "config"
        });
        return;
      }
      const clientId = parseAndValidateClientId(req, res);
      if (clientId === null) return;
      if (!clientId) {
        res.status(400).json({
          error: "`X-Qwen-Client-Id` header is required for runtime MCP mutation",
          code: "missing_client_id"
        });
        return;
      }
      try {
        const result = await bridge.addRuntimeMcpServer(
          name,
          config,
          clientId
        );
        res.status(200).json(result);
      } catch (err) {
        sendBridgeError2(res, err, {
          route: "POST /workspace/mcp/servers"
        });
      }
    }
  );
  app.delete(
    "/workspace/mcp/servers/:name",
    mutate({ strict: true }),
    async (req, res) => {
      const name = req.params["name"] ?? "";
      if (!validateMcpRuntimeServerName(name, res)) return;
      const clientId = parseAndValidateClientId(req, res);
      if (clientId === null) return;
      if (!clientId) {
        res.status(400).json({
          error: "`X-Qwen-Client-Id` header is required for runtime MCP mutation",
          code: "missing_client_id"
        });
        return;
      }
      try {
        const result = await bridge.removeRuntimeMcpServer(name, clientId);
        res.status(200).json(result);
      } catch (err) {
        sendBridgeError2(res, err, {
          route: "DELETE /workspace/mcp/servers/:name"
        });
      }
    }
  );
}
__name(registerWorkspaceMcpControlRoutes, "registerWorkspaceMcpControlRoutes");
function resolveTrustedMcpRuntime(registry, req, res) {
  const runtime = resolveWorkspaceRuntimeFromParam(registry, req, res);
  if (!runtime) return null;
  return requireTrustedWorkspaceRuntime(runtime, res) ? runtime : null;
}
__name(resolveTrustedMcpRuntime, "resolveTrustedMcpRuntime");
function registerWorkspaceQualifiedMcpControlRoutes(app, deps) {
  app.post(
    "/workspaces/:workspace/mcp/initialize",
    deps.mutate({ strict: true }),
    async (req, res) => {
      const runtime = resolveTrustedMcpRuntime(
        deps.workspaceRegistry,
        req,
        res
      );
      if (!runtime) return;
      const route = "POST /workspaces/:workspace/mcp/initialize";
      try {
        const result = await runtime.bridge.initializeWorkspaceMcp();
        res.status(202).json(result);
      } catch (err) {
        deps.sendBridgeError(res, err, { route });
      }
    }
  );
  app.post(
    "/workspaces/:workspace/mcp/reload",
    deps.mutate({ strict: true }),
    async (req, res) => {
      const runtime = resolveTrustedMcpRuntime(
        deps.workspaceRegistry,
        req,
        res
      );
      if (!runtime) return;
      const route = "POST /workspaces/:workspace/mcp/reload";
      try {
        const result = await runtime.bridge.reloadWorkspaceMcp();
        res.status(202).json(result);
      } catch (err) {
        deps.sendBridgeError(res, err, { route });
      }
    }
  );
  app.post(
    "/workspaces/:workspace/mcp/:server/restart",
    deps.mutate({ strict: true }),
    async (req, res) => {
      const runtime = resolveTrustedMcpRuntime(
        deps.workspaceRegistry,
        req,
        res
      );
      if (!runtime) return;
      const serverName = req.params["server"];
      if (!serverName || typeof serverName !== "string") {
        res.status(400).json({
          error: "Server name path parameter is required",
          code: "invalid_server_name"
        });
        return;
      }
      if (serverName.length > MAX_SERVER_NAME_LENGTH) {
        res.status(400).json({
          error: `Server name exceeds ${MAX_SERVER_NAME_LENGTH}-character limit`,
          code: "invalid_server_name"
        });
        return;
      }
      const clientId = parseAndValidateWorkspaceClientId(
        req,
        res,
        runtime.bridge
      );
      if (clientId === null) return;
      const rawEntryIndex = req.query["entryIndex"];
      let entryIndex;
      if (rawEntryIndex !== void 0 && rawEntryIndex !== "*") {
        const candidate = typeof rawEntryIndex === "string" ? rawEntryIndex : void 0;
        const parsed = candidate !== void 0 ? Number.parseInt(candidate, 10) : NaN;
        if (!Number.isInteger(parsed) || parsed < 0 || String(parsed) !== candidate) {
          res.status(400).json({
            error: '`entryIndex` query parameter must be a non-negative integer or "*"',
            code: "invalid_entry_index"
          });
          return;
        }
        entryIndex = parsed;
      }
      const route = "POST /workspaces/:workspace/mcp/:server/restart";
      try {
        const ctx = createBuildWorkspaceCtx(runtime.workspaceCwd)(
          route,
          clientId
        );
        const result = await runtime.workspaceService.restartMcpServer(
          ctx,
          serverName,
          entryIndex !== void 0 ? { entryIndex } : void 0
        );
        res.status(200).json(result);
      } catch (err) {
        deps.sendBridgeError(res, err, { route });
      }
    }
  );
  for (const [routeAction, bridgeAction] of [
    ["approve", "approve"],
    ["enable", "enable"],
    ["disable", "disable"],
    ["authenticate", "authenticate"],
    ["clear-auth", "clear-auth"]
  ]) {
    app.post(
      `/workspaces/:workspace/mcp/:server/${routeAction}`,
      deps.mutate({ strict: true }),
      async (req, res) => {
        const runtime = resolveTrustedMcpRuntime(
          deps.workspaceRegistry,
          req,
          res
        );
        if (!runtime) return;
        const serverName = req.params["server"];
        if (!serverName || typeof serverName !== "string") {
          res.status(400).json({
            error: "Server name path parameter is required",
            code: "invalid_server_name"
          });
          return;
        }
        if (serverName.length > MAX_SERVER_NAME_LENGTH) {
          res.status(400).json({
            error: `Server name exceeds ${MAX_SERVER_NAME_LENGTH}-character limit`,
            code: "invalid_server_name"
          });
          return;
        }
        const clientId = parseAndValidateWorkspaceClientId(
          req,
          res,
          runtime.bridge
        );
        if (clientId === null) return;
        const route = `POST /workspaces/:workspace/mcp/:server/${routeAction}`;
        try {
          const result = await runtime.bridge.manageMcpServer(
            serverName,
            bridgeAction,
            clientId
          );
          res.status(200).json(result);
        } catch (err) {
          deps.sendBridgeError(res, err, { route });
        }
      }
    );
  }
  app.post(
    "/workspaces/:workspace/mcp/servers",
    deps.mutate({ strict: true }),
    async (req, res) => {
      const runtime = resolveTrustedMcpRuntime(
        deps.workspaceRegistry,
        req,
        res
      );
      if (!runtime) return;
      const body = deps.safeBody(req);
      const name = body["name"];
      if (!validateMcpRuntimeServerName(name, res)) return;
      const config = body["config"];
      if (typeof config !== "object" || config === null || Array.isArray(config)) {
        res.status(400).json({
          error: "`config` must be a non-null object",
          code: "missing_required_field",
          field: "config"
        });
        return;
      }
      const clientId = parseAndValidateWorkspaceClientId(
        req,
        res,
        runtime.bridge
      );
      if (clientId === null) return;
      if (!clientId) {
        res.status(400).json({
          error: "`X-Qwen-Client-Id` header is required for runtime MCP mutation",
          code: "missing_client_id"
        });
        return;
      }
      const route = "POST /workspaces/:workspace/mcp/servers";
      try {
        const result = await runtime.bridge.addRuntimeMcpServer(
          name,
          config,
          clientId
        );
        res.status(200).json(result);
      } catch (err) {
        deps.sendBridgeError(res, err, { route });
      }
    }
  );
  app.delete(
    "/workspaces/:workspace/mcp/servers/:name",
    deps.mutate({ strict: true }),
    async (req, res) => {
      const runtime = resolveTrustedMcpRuntime(
        deps.workspaceRegistry,
        req,
        res
      );
      if (!runtime) return;
      const name = req.params["name"] ?? "";
      if (!validateMcpRuntimeServerName(name, res)) return;
      const clientId = parseAndValidateWorkspaceClientId(
        req,
        res,
        runtime.bridge
      );
      if (clientId === null) return;
      if (!clientId) {
        res.status(400).json({
          error: "`X-Qwen-Client-Id` header is required for runtime MCP mutation",
          code: "missing_client_id"
        });
        return;
      }
      const route = "DELETE /workspaces/:workspace/mcp/servers/:name";
      try {
        const result = await runtime.bridge.removeRuntimeMcpServer(
          name,
          clientId
        );
        res.status(200).json(result);
      } catch (err) {
        deps.sendBridgeError(res, err, { route });
      }
    }
  );
}
__name(registerWorkspaceQualifiedMcpControlRoutes, "registerWorkspaceQualifiedMcpControlRoutes");

// packages/cli/src/serve/routes/workspace-channel-control.ts
init_esbuild_shims();
function parseSelection(body, res) {
  const raw = body["selection"];
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
    res.status(400).json({
      error: "`selection` must be an object.",
      code: "invalid_channel_selection"
    });
    return void 0;
  }
  const selection = raw;
  if (selection["mode"] === "all") {
    if (selection["names"] !== void 0) {
      res.status(400).json({
        error: "`names` cannot be used with selection mode `all`.",
        code: "invalid_channel_selection"
      });
      return void 0;
    }
    return { mode: "all" };
  }
  if (selection["mode"] !== "names" || !Array.isArray(selection["names"])) {
    res.status(400).json({
      error: "Selection must use mode `all` or a `names` array.",
      code: "invalid_channel_selection"
    });
    return void 0;
  }
  if (!selection["names"].every((name) => typeof name === "string")) {
    res.status(400).json({
      error: "Every channel name must be a string.",
      code: "invalid_channel_selection"
    });
    return void 0;
  }
  try {
    const normalized = normalizeServeChannelSelection(
      selection["names"]
    );
    if (!normalized || normalized.mode !== "names") {
      throw new Error("At least one named channel is required.");
    }
    return normalized;
  } catch (error2) {
    res.status(400).json({
      error: error2 instanceof Error ? error2.message : String(error2),
      code: "invalid_channel_selection"
    });
    return void 0;
  }
}
__name(parseSelection, "parseSelection");
function sanitizeControlDiagnostic(value, maxLength) {
  return sanitizeLogText(
    redactLogCredentials(normalizeWorkerDiagnostic(value)),
    maxLength
  );
}
__name(sanitizeControlDiagnostic, "sanitizeControlDiagnostic");
function startupFailureResponseFields(error2) {
  if (!error2 || typeof error2 !== "object") return {};
  let rawFailures;
  let rawTruncated;
  try {
    rawFailures = Reflect.get(error2, "startupFailures");
    rawTruncated = Reflect.get(error2, "startupFailuresTruncated");
  } catch {
    return {};
  }
  if (!Array.isArray(rawFailures)) return {};
  let limitedFailures;
  let rawFailureCount;
  try {
    limitedFailures = rawFailures.slice(0, MAX_CHANNEL_STARTUP_FAILURES);
    rawFailureCount = rawFailures.length;
  } catch {
    return {};
  }
  const startupFailures = limitedFailures.flatMap((raw) => {
    try {
      if (!raw || typeof raw !== "object" || Array.isArray(raw)) return [];
      const failure = raw;
      if (typeof failure["workspaceCwd"] !== "string" || failure["workspaceCwd"].length === 0 || typeof failure["channel"] !== "string" || failure["channel"].length === 0 || failure["phase"] !== "connect" || typeof failure["message"] !== "string" || failure["message"].length === 0 || failure["code"] !== void 0 && (typeof failure["code"] !== "string" || failure["code"].length === 0)) {
        return [];
      }
      const workspaceCwd = sanitizeControlDiagnostic(
        failure["workspaceCwd"],
        MAX_WORKSPACE_PATH_LENGTH
      );
      const channel = sanitizeControlDiagnostic(
        failure["channel"],
        MAX_CHANNEL_STARTUP_FAILURE_CHANNEL_LENGTH
      );
      const message = sanitizeControlDiagnostic(
        failure["message"],
        MAX_CHANNEL_STARTUP_FAILURE_MESSAGE_LENGTH
      );
      const code = typeof failure["code"] === "string" ? sanitizeControlDiagnostic(
        failure["code"],
        MAX_CHANNEL_STARTUP_FAILURE_CODE_LENGTH
      ) : void 0;
      if (!workspaceCwd || !channel || !message) return [];
      return [
        {
          workspaceCwd,
          channel,
          phase: "connect",
          ...code ? { code } : {},
          message
        }
      ];
    } catch {
      return [];
    }
  });
  if (startupFailures.length === 0) return {};
  const truncated = rawTruncated === true || rawFailureCount > MAX_CHANNEL_STARTUP_FAILURES;
  return {
    startupFailures,
    ...truncated ? { startupFailuresTruncated: true } : {}
  };
}
__name(startupFailureResponseFields, "startupFailureResponseFields");
function sendChannelControlError(res, error2, getState) {
  const code = error2 && typeof error2 === "object" && "code" in error2 ? error2.code : void 0;
  const rawMessage = error2 instanceof Error ? error2.message : String(error2);
  const message = code === "channel_worker_start_failed" ? sanitizeControlDiagnostic(
    rawMessage,
    MAX_CHANNEL_STARTUP_FAILURE_MESSAGE_LENGTH
  ) : redactLogCredentials(rawMessage);
  if (code === "channel_workspace_mismatch" || code === "ambiguous_channel_workspace") {
    res.status(400).json({ error: message, code });
    return true;
  }
  if (code === "untrusted_workspace") {
    res.status(403).json({ error: message, code });
    return true;
  }
  if (code === "channel_service_conflict") {
    const conflict = error2;
    res.status(409).json({
      error: message,
      code,
      ...typeof conflict.owner === "string" ? { owner: conflict.owner } : {},
      ...typeof conflict.pid === "number" ? { pid: conflict.pid } : {}
    });
    return true;
  }
  if (code === "daemon_draining") {
    res.status(503).json({
      error: message,
      code,
      state: getState()
    });
    return true;
  }
  if (code !== "channel_worker_not_enabled" && code !== "channel_worker_stop_failed" && code !== "channel_worker_start_failed") {
    return false;
  }
  const controlError = error2;
  const status = code === "channel_worker_not_enabled" ? 409 : code === "channel_worker_stop_failed" ? 500 : 502;
  res.status(status).json({
    error: message,
    code,
    ...typeof controlError.rolledBack === "boolean" ? { rolledBack: controlError.rolledBack } : {},
    ...typeof controlError.rollbackError === "string" && controlError.rollbackError ? {
      rollbackError: sanitizeControlDiagnostic(
        controlError.rollbackError,
        512
      )
    } : {},
    ...code === "channel_worker_start_failed" ? startupFailureResponseFields(error2) : {},
    state: getState()
  });
  return true;
}
__name(sendChannelControlError, "sendChannelControlError");
function registerWorkspaceChannelControlRoutes(app, deps) {
  const parseClient = /* @__PURE__ */ __name((req, res) => deps.parseAndValidateClientId(req, res) !== null, "parseClient");
  app.get("/workspace/channel", (_req, res) => {
    res.status(200).json(deps.getChannelWorkerControl());
  });
  if (deps.setChannelWorkerSelection)
    app.put(
      "/workspace/channel",
      deps.mutate({ strict: true }),
      async (req, res) => {
        if (!parseClient(req, res)) return;
        if (deps.isDaemonDraining?.()) {
          res.status(503).json({
            error: "Daemon is shutting down.",
            code: "daemon_draining",
            state: deps.getChannelWorkerControl()
          });
          return;
        }
        const selection = parseSelection(deps.safeBody(req), res);
        if (!selection) return;
        try {
          const result = await deps.setChannelWorkerSelection(selection);
          const { created, ...response } = result;
          res.status(created === true ? 201 : 200).json(response);
        } catch (error2) {
          if (sendChannelControlError(res, error2, deps.getChannelWorkerControl)) {
            return;
          }
          deps.sendBridgeError(res, error2, { route: "PUT /workspace/channel" });
        }
      }
    );
  if (deps.stopChannelWorker)
    app.delete(
      "/workspace/channel",
      deps.mutate({ strict: true }),
      async (req, res) => {
        if (!parseClient(req, res)) return;
        if (deps.isDaemonDraining?.()) {
          res.status(503).json({
            error: "Daemon is shutting down.",
            code: "daemon_draining",
            state: deps.getChannelWorkerControl()
          });
          return;
        }
        try {
          res.status(200).json(await deps.stopChannelWorker());
        } catch (error2) {
          if (sendChannelControlError(res, error2, deps.getChannelWorkerControl)) {
            return;
          }
          deps.sendBridgeError(res, error2, {
            route: "DELETE /workspace/channel"
          });
        }
      }
    );
  if (deps.reloadChannelWorker) {
    app.post(
      "/workspace/channel/reload",
      deps.mutate({ strict: true }),
      async (req, res) => {
        if (!parseClient(req, res)) return;
        if (deps.isDaemonDraining?.()) {
          res.status(503).json({
            error: "Daemon is shutting down.",
            code: "daemon_draining",
            state: deps.getChannelWorkerControl()
          });
          return;
        }
        if (!deps.isManagerInitializing?.() && !deps.getChannelWorkerControl().enabled) {
          res.status(409).json({
            error: "This daemon has no channel worker to reload. Set a runtime selection first.",
            code: "channel_worker_not_enabled"
          });
          return;
        }
        try {
          const worker = await deps.reloadChannelWorker();
          res.status(200).json({ reloaded: true, worker });
        } catch (error2) {
          if (sendChannelControlError(res, error2, deps.getChannelWorkerControl)) {
            return;
          }
          deps.sendBridgeError(res, error2, {
            route: "POST /workspace/channel/reload"
          });
        }
      }
    );
  }
}
__name(registerWorkspaceChannelControlRoutes, "registerWorkspaceChannelControlRoutes");

// packages/cli/src/serve/routes/workspace-tools.ts
init_esbuild_shims();
function registerWorkspaceToolsRoutes(app, deps) {
  const {
    boundWorkspace,
    workspace,
    mutate,
    safeBody: safeBody2,
    sendBridgeError: sendBridgeError2,
    parseAndValidateClientId
  } = deps;
  const buildWorkspaceCtx = createBuildWorkspaceCtx(boundWorkspace);
  app.post(
    "/workspace/tools/:name/enable",
    mutate({ strict: true }),
    async (req, res) => {
      const rawToolName = req.params["name"];
      if (!rawToolName || typeof rawToolName !== "string") {
        res.status(400).json({
          error: "Tool name path parameter is required",
          code: "invalid_tool_name"
        });
        return;
      }
      const toolName = rawToolName.trim();
      if (toolName.length === 0) {
        res.status(400).json({
          error: "Tool name path parameter is required",
          code: "invalid_tool_name"
        });
        return;
      }
      if (toolName.length > MAX_TOOL_NAME_LENGTH) {
        res.status(400).json({
          error: `Tool name exceeds ${MAX_TOOL_NAME_LENGTH}-character limit`,
          code: "invalid_tool_name"
        });
        return;
      }
      const body = safeBody2(req);
      const enabled = body["enabled"];
      if (typeof enabled !== "boolean") {
        res.status(400).json({
          error: "`enabled` is required and must be a boolean",
          code: "invalid_enabled_flag"
        });
        return;
      }
      const clientId = parseAndValidateClientId(req, res);
      if (clientId === null) return;
      try {
        const ctx = buildWorkspaceCtx(
          "POST /workspace/tools/:name/enable",
          clientId
        );
        const result = await workspace.setWorkspaceToolEnabled(
          ctx,
          toolName,
          enabled
        );
        res.status(200).json(result);
      } catch (err) {
        sendBridgeError2(res, err, {
          route: "POST /workspace/tools/:name/enable"
        });
      }
    }
  );
}
__name(registerWorkspaceToolsRoutes, "registerWorkspaceToolsRoutes");
function registerWorkspaceQualifiedToolsRoutes(app, deps) {
  app.post(
    "/workspaces/:workspace/tools/:name/enable",
    deps.mutate({ strict: true }),
    async (req, res) => {
      const runtime = resolveWorkspaceRuntimeFromParam(
        deps.workspaceRegistry,
        req,
        res
      );
      if (!runtime || !requireTrustedWorkspaceRuntime(runtime, res)) return;
      const rawToolName = req.params["name"];
      if (!rawToolName || typeof rawToolName !== "string") {
        res.status(400).json({
          error: "Tool name path parameter is required",
          code: "invalid_tool_name"
        });
        return;
      }
      const toolName = rawToolName.trim();
      if (toolName.length === 0) {
        res.status(400).json({
          error: "Tool name path parameter is required",
          code: "invalid_tool_name"
        });
        return;
      }
      if (toolName.length > MAX_TOOL_NAME_LENGTH) {
        res.status(400).json({
          error: `Tool name exceeds ${MAX_TOOL_NAME_LENGTH}-character limit`,
          code: "invalid_tool_name"
        });
        return;
      }
      const body = deps.safeBody(req);
      const enabled = body["enabled"];
      if (typeof enabled !== "boolean") {
        res.status(400).json({
          error: "`enabled` is required and must be a boolean",
          code: "invalid_enabled_flag"
        });
        return;
      }
      const clientId = parseAndValidateWorkspaceClientId(
        req,
        res,
        runtime.bridge
      );
      if (clientId === null) return;
      const route = "POST /workspaces/:workspace/tools/:name/enable";
      try {
        const ctx = createBuildWorkspaceCtx(runtime.workspaceCwd)(
          route,
          clientId
        );
        const result = await runtime.workspaceService.setWorkspaceToolEnabled(
          ctx,
          toolName,
          enabled
        );
        res.status(200).json(result);
      } catch (err) {
        deps.sendBridgeError(res, err, { route });
      }
    }
  );
}
__name(registerWorkspaceQualifiedToolsRoutes, "registerWorkspaceQualifiedToolsRoutes");

// packages/cli/src/serve/routes/workspace-skills.ts
init_esbuild_shims();
function parseSkillToggleRequest(req, res, safeBody2) {
  const rawSkillName = req.params["name"];
  if (!rawSkillName || typeof rawSkillName !== "string") {
    res.status(400).json({
      error: "Skill name path parameter is required",
      code: "invalid_skill_name"
    });
    return void 0;
  }
  const skillName = rawSkillName.trim();
  if (skillName.length === 0) {
    res.status(400).json({
      error: "Skill name path parameter is required",
      code: "invalid_skill_name"
    });
    return void 0;
  }
  if (skillName.length > MAX_SKILL_NAME_LENGTH) {
    res.status(400).json({
      error: `Skill name exceeds ${MAX_SKILL_NAME_LENGTH}-character limit`,
      code: "invalid_skill_name"
    });
    return void 0;
  }
  const enabled = safeBody2(req)["enabled"];
  if (typeof enabled !== "boolean") {
    res.status(400).json({
      error: "`enabled` is required and must be a boolean",
      code: "invalid_enabled_flag"
    });
    return void 0;
  }
  return { skillName, enabled };
}
__name(parseSkillToggleRequest, "parseSkillToggleRequest");
function registerWorkspaceSkillsRoutes(app, deps) {
  const buildWorkspaceCtx = createBuildWorkspaceCtx(
    deps.workspaceRuntime.workspaceCwd
  );
  const route = "POST /workspace/skills/:name/enable";
  app.post(
    "/workspace/skills/:name/enable",
    deps.mutate({ strict: true }),
    async (req, res) => {
      if (!requireTrustedWorkspaceRuntime(deps.workspaceRuntime, res)) return;
      const input = parseSkillToggleRequest(req, res, deps.safeBody);
      if (!input) return;
      const clientId = deps.parseAndValidateClientId(req, res);
      if (clientId === null) return;
      try {
        const result = await deps.workspaceRuntime.workspaceService.setWorkspaceSkillEnabled(
          buildWorkspaceCtx(route, clientId),
          input.skillName,
          input.enabled
        );
        res.status(200).json(result);
      } catch (err) {
        deps.sendBridgeError(res, err, { route });
      }
    }
  );
}
__name(registerWorkspaceSkillsRoutes, "registerWorkspaceSkillsRoutes");
function registerWorkspaceQualifiedSkillsRoutes(app, deps) {
  const route = "POST /workspaces/:workspace/skills/:name/enable";
  app.post(
    "/workspaces/:workspace/skills/:name/enable",
    deps.mutate({ strict: true }),
    async (req, res) => {
      const runtime = resolveWorkspaceRuntimeFromParam(
        deps.workspaceRegistry,
        req,
        res
      );
      if (!runtime || !requireTrustedWorkspaceRuntime(runtime, res)) return;
      const input = parseSkillToggleRequest(req, res, deps.safeBody);
      if (!input) return;
      const clientId = parseAndValidateWorkspaceClientId(
        req,
        res,
        runtime.bridge
      );
      if (clientId === null) return;
      try {
        const result = await runtime.workspaceService.setWorkspaceSkillEnabled(
          createBuildWorkspaceCtx(runtime.workspaceCwd)(route, clientId),
          input.skillName,
          input.enabled
        );
        res.status(200).json(result);
      } catch (err) {
        deps.sendBridgeError(res, err, { route });
      }
    }
  );
}
__name(registerWorkspaceQualifiedSkillsRoutes, "registerWorkspaceQualifiedSkillsRoutes");

// packages/cli/src/serve/routes/channel-webhooks.ts
init_esbuild_shims();
var import_express4 = __toESM(require_express(), 1);
import { createHash as createHash4, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
var PROTOTYPE_POLLUTION_KEYS = /* @__PURE__ */ new Set([
  "__proto__",
  "constructor",
  "prototype"
]);
var MAX_PAYLOAD_DEPTH = 64;
function registerChannelWebhookRoutes(app, deps) {
  app.post(
    "/channels/:channelName/webhooks/:source",
    ...deps.rateLimiter ? [createWebhookRateLimitMiddleware(deps)] : [],
    (req, res, next) => {
      const channelName = req.params["channelName"];
      const source = req.params["source"];
      if (!channelName || !source) {
        res.status(404).json({ error: "Channel webhook route not found" });
        return;
      }
      const sources = deps.getChannelsConfig()[channelName]?.webhooks?.sources;
      const sourceConfig = sources && Object.hasOwn(sources, source) ? sources[source] : void 0;
      if (!sourceConfig) {
        deps.daemonLog?.warn("channel webhook authentication failed", {
          channelName,
          source
        });
        res.status(401).json({ error: "Invalid webhook secret" });
        return;
      }
      const secret = sourceConfig.secret;
      if (typeof secret !== "string" || secret.length === 0 || !matchesWebhookSecret(req.get("x-qwen-webhook-secret"), secret)) {
        deps.daemonLog?.warn("channel webhook authentication failed", {
          channelName,
          source
        });
        res.status(401).json({ error: "Invalid webhook secret" });
        return;
      }
      if (deps.rateLimiter && !deps.rateLimiter.checkRate(
        `webhook:${channelName}:${source}`,
        "mutation"
      )) {
        sendWebhookRateLimitExceeded(res);
        return;
      }
      const locals = res.locals;
      locals.channelWebhook = { channelName, source, sourceConfig };
      next();
    },
    import_express4.default.json({ limit: "1mb" }),
    async (req, res) => {
      const locals = res.locals;
      const webhook = locals.channelWebhook;
      if (!webhook) {
        res.status(401).json({ error: "Invalid webhook secret" });
        return;
      }
      const { channelName, source, sourceConfig } = webhook;
      const body = deps.safeBody(req);
      const eventType = readRequiredBodyString(body, "eventType", res);
      if (!eventType) {
        return;
      }
      const targetRef = readRequiredBodyString(body, "targetRef", res);
      if (!targetRef) {
        return;
      }
      const title = readRequiredBodyString(body, "title", res);
      if (!title) {
        return;
      }
      if (!Object.hasOwn(sourceConfig.targets, targetRef)) {
        res.status(404).json({ error: "Unknown channel webhook target" });
        return;
      }
      const payload = readPayload(body, res);
      if (!payload) {
        return;
      }
      const task = {
        channelName,
        source,
        eventType,
        targetRef,
        title,
        payload
      };
      if (typeof body["summary"] === "string") {
        task.summary = body["summary"];
      }
      try {
        await deps.enqueueWebhookTask(task);
        deps.daemonLog?.info("channel webhook task accepted", {
          channelName,
          source,
          eventType,
          targetRef
        });
      } catch (error2) {
        const enqueueError = classifyChannelWebhookEnqueueError(error2);
        deps.daemonLog?.warn("channel webhook task enqueue failed", {
          channelName,
          source,
          eventType,
          targetRef,
          code: enqueueError.code
        });
        res.status(enqueueError.status).json({
          error: "Failed to enqueue channel webhook task",
          code: enqueueError.code,
          ...enqueueError.detail ? { detail: enqueueError.detail } : {}
        });
        return;
      }
      res.status(202).json({ accepted: true });
    }
  );
}
__name(registerChannelWebhookRoutes, "registerChannelWebhookRoutes");
function createWebhookRateLimitMiddleware(deps) {
  return (req, res, next) => {
    if (!deps.rateLimiter) {
      next();
      return;
    }
    if (deps.rateLimiter.checkRate(
      `webhook:preauth:${readRequestAddress(req)}`,
      "mutation"
    )) {
      next();
      return;
    }
    sendWebhookRateLimitExceeded(res);
  };
}
__name(createWebhookRateLimitMiddleware, "createWebhookRateLimitMiddleware");
function readRequestAddress(req) {
  return req.ip || req.socket.remoteAddress || "unknown";
}
__name(readRequestAddress, "readRequestAddress");
function sendWebhookRateLimitExceeded(res) {
  res.status(429).json({
    error: "Rate limit exceeded",
    code: "rate_limit_exceeded",
    tier: "mutation"
  });
}
__name(sendWebhookRateLimitExceeded, "sendWebhookRateLimitExceeded");
function readRequiredBodyString(body, key, res) {
  const value = body[key];
  if (typeof value !== "string" || value.length === 0) {
    res.status(400).json({
      error: `Body field "${key}" must be a non-empty string`
    });
    return void 0;
  }
  return value;
}
__name(readRequiredBodyString, "readRequiredBodyString");
function matchesWebhookSecret(candidate, expected) {
  if (typeof candidate !== "string") {
    return false;
  }
  const expectedDigest = createHash4("sha256").update(expected).digest();
  const candidateDigest = createHash4("sha256").update(candidate).digest();
  return timingSafeEqual2(expectedDigest, candidateDigest);
}
__name(matchesWebhookSecret, "matchesWebhookSecret");
function readPayload(body, res) {
  const payload = body["payload"];
  if (payload === void 0) {
    return {};
  }
  if (typeof payload === "object" && payload !== null && !Array.isArray(payload)) {
    if (!isWithinPayloadDepth(payload, MAX_PAYLOAD_DEPTH)) {
      res.status(400).json({
        error: `Body field "payload" exceeds maximum nesting depth (${MAX_PAYLOAD_DEPTH})`
      });
      return void 0;
    }
    return Object.fromEntries(
      Object.entries(payload).filter(
        ([key]) => !PROTOTYPE_POLLUTION_KEYS.has(key)
      )
    );
  }
  res.status(400).json({
    error: 'Body field "payload" must be an object when provided'
  });
  return void 0;
}
__name(readPayload, "readPayload");
function isWithinPayloadDepth(value, maxDepth) {
  const stack = [{ value, depth: 0 }];
  while (stack.length > 0) {
    const current = stack.pop();
    if (!current) continue;
    if (current.depth > maxDepth) return false;
    if (typeof current.value !== "object" || current.value === null) continue;
    const children = Array.isArray(current.value) ? current.value : Object.values(current.value);
    for (const child of children) {
      stack.push({ value: child, depth: current.depth + 1 });
    }
  }
  return true;
}
__name(isWithinPayloadDepth, "isWithinPayloadDepth");
function classifyChannelWebhookEnqueueError(error2) {
  if (isChannelWebhookEnqueueError(error2)) {
    return {
      status: statusForChannelWebhookEnqueueCode(error2.code),
      code: error2.code
    };
  }
  return {
    status: 500,
    code: "channel_webhook_enqueue_failed"
  };
}
__name(classifyChannelWebhookEnqueueError, "classifyChannelWebhookEnqueueError");
function statusForChannelWebhookEnqueueCode(code) {
  switch (code) {
    case "channel_webhook_invalid_task":
      return 400;
    case "channel_webhook_target_unavailable":
      return 409;
    case "channel_webhook_enqueue_timeout":
      return 504;
    case "channel_worker_unavailable":
    case "channel_webhook_queue_full":
      return 503;
    case "channel_webhook_enqueue_failed":
      return 500;
    default:
      return 500;
  }
}
__name(statusForChannelWebhookEnqueueCode, "statusForChannelWebhookEnqueueCode");

// packages/cli/src/serve/server.ts
var warnedDefaultTrust = false;
function loadServeChannelWebhookConfigs(sources) {
  const parsed = {};
  for (const source of sources) {
    let channelsConfig;
    try {
      channelsConfig = loadChannelsConfig(source.workspaceCwd);
    } catch (error2) {
      writeStderrLine(
        `[daemon] Skipping webhook config source ${JSON.stringify(source.workspaceCwd)}: ${error2 instanceof Error ? error2.message : String(error2)}`
      );
      continue;
    }
    const selectedChannels = source.channelNames ? new Set(source.channelNames) : void 0;
    for (const [channelName, rawConfig] of Object.entries(channelsConfig)) {
      if (selectedChannels && !selectedChannels.has(channelName) || typeof rawConfig !== "object" || rawConfig === null) {
        continue;
      }
      let webhooks;
      try {
        webhooks = parseChannelWebhookConfigLenient(
          channelName,
          rawConfig,
          (webhookSource, sourceError) => {
            const sourceMessage = sourceError instanceof Error ? sourceError.message : String(sourceError);
            writeStderrLine(
              `[daemon] Skipping malformed webhook source "${webhookSource}" for channel "${channelName}": ${sourceMessage}`
            );
          },
          source.env
        );
      } catch (error2) {
        const message = error2 instanceof Error ? error2.message : String(error2);
        writeStderrLine(
          `[daemon] Skipping malformed webhook config for channel "${channelName}": ${message}`
        );
        continue;
      }
      if (webhooks) {
        parsed[channelName] = { webhooks };
      }
    }
  }
  return parsed;
}
__name(loadServeChannelWebhookConfigs, "loadServeChannelWebhookConfigs");
function describeRegistryPrimaryForConflict(registry) {
  return `registry primary cwd=${JSON.stringify(registry.primary.workspaceCwd)}, workspaceId=${JSON.stringify(registry.primary.workspaceId)}`;
}
__name(describeRegistryPrimaryForConflict, "describeRegistryPrimaryForConflict");
function getRuntimeEffectiveEnv(metadata) {
  if (!metadata || metadata.mode === "parent-process") {
    return metadata?.effectiveEnv;
  }
  return metadata.effectiveEnv ?? {};
}
__name(getRuntimeEffectiveEnv, "getRuntimeEffectiveEnv");
var DEFAULT_SESSION_IDLE_TIMEOUT_MS = 30 * 6e4;
var KEEPALIVE_MIN_INTERVAL_MS = 3e4;
var KEEPALIVE_MAX_INTERVAL_MS = 10 * 6e4;
function computeKeepaliveIntervalMs(idleTimeoutMs) {
  if (idleTimeoutMs <= 0) return KEEPALIVE_MAX_INTERVAL_MS;
  const target = Math.min(
    Math.max(KEEPALIVE_MIN_INTERVAL_MS, Math.floor(idleTimeoutMs / 3)),
    KEEPALIVE_MAX_INTERVAL_MS
  );
  return Math.max(1, Math.min(target, Math.floor(idleTimeoutMs / 2)));
}
__name(computeKeepaliveIntervalMs, "computeKeepaliveIntervalMs");
function createServeApp(opts, getPort = () => opts.port, deps = {}) {
  if (deps.workspaceRuntimeRemoval && !deps.voiceCoordinator) {
    throw new Error(
      "createServeApp: deps.workspaceRuntimeRemoval requires the matching deps.voiceCoordinator."
    );
  }
  const app = (0, import_express5.default)();
  const injectedWorkspaceRegistry = deps.workspaceRegistry;
  const boundWorkspace = injectedWorkspaceRegistry?.primary.workspaceCwd ?? deps.boundWorkspace ?? canonicalizeWorkspace(opts.workspace ?? process.cwd());
  if (injectedWorkspaceRegistry) {
    const primary = injectedWorkspaceRegistry.primary;
    const registryConflictCandidates = [
      {
        depName: "deps.boundWorkspace",
        depValue: deps.boundWorkspace,
        registryValue: primary.workspaceCwd,
        detail: `deps.boundWorkspace=${JSON.stringify(deps.boundWorkspace)}`
      },
      {
        depName: "deps.bridge",
        depValue: deps.bridge,
        registryValue: primary.bridge,
        detail: "deps.bridge is a different object"
      },
      {
        depName: "deps.workspace",
        depValue: deps.workspace,
        registryValue: primary.workspaceService,
        detail: "deps.workspace is a different object"
      },
      {
        depName: "deps.fsFactory",
        depValue: deps.fsFactory,
        registryValue: primary.routeFileSystemFactory,
        detail: "deps.fsFactory is a different object"
      },
      {
        depName: "deps.clientMcpSenderRegistry",
        depValue: deps.clientMcpSenderRegistry,
        registryValue: primary.clientMcpSenderRegistry,
        detail: "deps.clientMcpSenderRegistry is a different object"
      }
    ];
    for (const candidate of registryConflictCandidates) {
      if (candidate.depValue === void 0 || candidate.depValue === candidate.registryValue) {
        continue;
      }
      throw new Error(
        `createServeApp: workspaceRegistry conflicts with ${candidate.depName}: ${describeRegistryPrimaryForConflict(
          injectedWorkspaceRegistry
        )}; ${candidate.detail}.`
      );
    }
  }
  if (!injectedWorkspaceRegistry && !deps.fsFactory && !deps.bridge && !warnedDefaultTrust) {
    warnedDefaultTrust = true;
    process.stderr.write(
      "qwen serve: createServeApp default fsFactory uses trusted=false \u2014 agent ACP writeTextFile calls will reject with untrusted_workspace. Inject deps.fsFactory (with explicit trust) or deps.bridge to override.\n"
    );
  }
  const fsFactory = injectedWorkspaceRegistry?.primary.routeFileSystemFactory ?? resolveBridgeFsFactory({
    boundWorkspaces: [boundWorkspace],
    injected: deps.fsFactory,
    trusted: false
  });
  const tokenConfigured = typeof opts.token === "string" && opts.token.length > 0;
  const sessionShellCommandEnabled = opts.enableSessionShell === true && tokenConfigured;
  if (opts.clientMcpOverWs === true && deps.bridge && !injectedWorkspaceRegistry && !deps.clientMcpSenderRegistry) {
    throw new Error(
      "createServeApp: deps.bridge requires deps.clientMcpSenderRegistry when clientMcpOverWs is enabled (the bridge is already wired to its own sender; a fresh registry here would be an orphan)."
    );
  }
  const clientMcpSenderRegistry = injectedWorkspaceRegistry?.primary.clientMcpSenderRegistry ?? deps.clientMcpSenderRegistry ?? new ClientMcpSenderRegistry();
  const primaryRuntimeEnvMetadata = injectedWorkspaceRegistry?.primary.env ?? deps.primaryRuntimeEnv;
  const primaryEffectiveEnv = getRuntimeEffectiveEnv(primaryRuntimeEnvMetadata);
  const { languageCodes, currentServeFeatures, invalidateServeFeaturesCache } = createServeFeatures({
    opts,
    boundWorkspace,
    persistSettingAvailable: deps.persistSetting !== void 0,
    sessionArtifactsPersistenceAvailable: deps.sessionArtifactsPersistenceAvailable !== false,
    sessionGenerationAvailable: /* @__PURE__ */ __name(() => {
      const runtimes = workspaceRegistry.list();
      return runtimes.length > 0 && runtimes.every(
        (runtime) => runtime.bridge.generateSessionContent !== void 0
      );
    }, "sessionGenerationAvailable"),
    // Registry injection supplies the primary workspace service through the
    // runtime, so it has the same reload surface as legacy deps.workspace.
    reloadAvailable: deps.workspace !== void 0 || injectedWorkspaceRegistry !== void 0,
    channelControlAvailable: deps.getChannelWorkerControl !== void 0 && deps.setChannelWorkerSelection !== void 0 && deps.stopChannelWorker !== void 0,
    channelReloadAvailable: /* @__PURE__ */ __name(() => {
      if (deps.reloadChannelWorker === void 0) return false;
      const control = deps.getChannelWorkerControl?.();
      if (control) {
        return control.enabled && control.selection !== null && control.workers.length > 0;
      }
      return deps.getChannelWorkerSnapshots?.().some((worker) => worker.enabled) || deps.getChannelWorkerSnapshot?.().enabled || false;
    }, "channelReloadAvailable"),
    sessionShellCommandEnabled,
    multiWorkspaceSessionsEnabled: /* @__PURE__ */ __name(() => workspaceRegistry.list().length > 1, "multiWorkspaceSessionsEnabled"),
    persistentWorkspaceRegistrationAvailable: deps.workspaceRegistrationStore !== void 0,
    workspaceRuntimeRemovalAvailable: deps.workspaceRuntimeRemoval !== void 0,
    ...primaryEffectiveEnv ? { env: primaryEffectiveEnv } : {}
  });
  app.locals.invalidateServeFeaturesCache = invalidateServeFeaturesCache;
  const statusProvider = deps.statusProvider ?? createDaemonStatusProvider(
    primaryEffectiveEnv ? { env: primaryEffectiveEnv } : {}
  );
  let defaultBridgeForAdmission;
  const totalSessionAdmission = !deps.bridge && !injectedWorkspaceRegistry ? createTotalSessionAdmissionController({
    maxTotalSessions: opts.maxTotalSessions,
    getBridges: /* @__PURE__ */ __name(() => defaultBridgeForAdmission ? [defaultBridgeForAdmission] : [], "getBridges")
  }) : void 0;
  const defaultSessionOwnerIndex = !injectedWorkspaceRegistry ? createWorkspaceSessionOwnerIndex() : void 0;
  const bridge = injectedWorkspaceRegistry?.primary.bridge ?? deps.bridge ?? createAcpSessionBridge({
    maxSessions: opts.maxSessions,
    ...totalSessionAdmission ? { freshSessionAdmission: totalSessionAdmission.admit } : {},
    ...defaultSessionOwnerIndex ? {
      sessionLifecycle: defaultSessionOwnerIndex.handleBridgeSessionLifecycle
    } : {},
    maxPendingPromptsPerSession: opts.maxPendingPromptsPerSession,
    eventRingSize: opts.eventRingSize,
    compactedReplayMaxBytes: opts.compactedReplayMaxBytes,
    permissionResponseTimeoutMs: opts.permissionResponseTimeoutMs,
    boundWorkspace,
    sessionShellCommandEnabled,
    // Wire the production status provider so direct embeds / tests
    // that don't inject `deps.bridge` get daemon env + preflight cells.
    statusProvider,
    // Wire the WorkspaceFileSystem adapter so ACP writeTextFile /
    // readTextFile pick up trust / TOCTOU / audit.
    fileSystem: createBridgeFileSystemAdapter(fsFactory),
    // Reverse tool channel: answer the child's `client_mcp/message`
    // ext-method by reaching the WS connection that hosts the named server.
    clientMcpSender: clientMcpSenderRegistry.lookup
  });
  if (!injectedWorkspaceRegistry && !deps.bridge) {
    defaultBridgeForAdmission = bridge;
  }
  const archiveCoordinator = new SessionArchiveCoordinator();
  installSelfOriginStripMiddleware(app, getPort);
  app.locals.fsFactory = fsFactory;
  app.locals.boundWorkspace = boundWorkspace;
  const { deviceFlowRegistry, getSupportedDeviceFlowProviders } = setupDeviceFlowRegistry({
    app,
    bridge,
    registry: deps.deviceFlowRegistry,
    providers: deps.deviceFlowProviders,
    // Phase 4: fan device-flow events out to the primary and every trusted
    // secondary runtime bridge, so workspace-qualified ACP clients receive
    // their own flow's events. Resolved lazily: the registry is created
    // before the workspace registry exists, but by the time a flow emits,
    // `app.locals` holds the populated registry.
    resolveEventBridges: /* @__PURE__ */ __name(() => {
      const reg = app.locals.workspaceRegistry;
      if (!reg) return [bridge];
      return reg.list().filter((rt) => rt.primary || rt.trusted).map((rt) => rt.bridge);
    }, "resolveEventBridges")
  });
  const { daemonLog } = deps;
  const sendBridgeError2 = /* @__PURE__ */ __name((res, err, ctx) => sendBridgeError(res, err, ctx, daemonLog), "sendBridgeError");
  const sendPermissionVoteError2 = /* @__PURE__ */ __name((res, err, ctx) => sendPermissionVoteError(res, err, ctx, daemonLog), "sendPermissionVoteError");
  const workspace = injectedWorkspaceRegistry?.primary.workspaceService ?? deps.workspace ?? createDaemonWorkspaceService({
    boundWorkspace,
    contextFilename: deps.contextFilename ?? "QWEN.md",
    statusProvider,
    workspaceProvidersStatusProvider: createWorkspaceProvidersStatusProvider(
      primaryEffectiveEnv ? { env: primaryEffectiveEnv } : {}
    ),
    workspaceSkillsStatusProvider: createWorkspaceSkillsStatusProvider(),
    ...primaryEffectiveEnv ? { voiceEnv: primaryEffectiveEnv } : {},
    isChannelLive: /* @__PURE__ */ __name(() => bridge.isChannelLive(), "isChannelLive"),
    persistDisabledTools: deps.persistDisabledTools ?? (async () => {
      throw new Error(
        "setWorkspaceToolEnabled requires persistDisabledTools in ServeAppDeps"
      );
    }),
    persistDisabledSkills: deps.persistDisabledSkills ?? (async () => {
      throw new Error(
        "setWorkspaceSkillEnabled requires persistDisabledSkills in ServeAppDeps"
      );
    }),
    queryWorkspaceStatus: /* @__PURE__ */ __name((method, idle) => bridge.queryWorkspaceStatus(method, idle), "queryWorkspaceStatus"),
    invokeWorkspaceCommand: /* @__PURE__ */ __name((method, params, invokeOpts) => bridge.invokeWorkspaceCommand(method, params, invokeOpts), "invokeWorkspaceCommand"),
    preheatAcpChild: /* @__PURE__ */ __name(() => bridge.preheat(), "preheatAcpChild"),
    refreshExtensionsForAllSessions: /* @__PURE__ */ __name(() => bridge.refreshExtensionsForAllSessions(), "refreshExtensionsForAllSessions"),
    ...deps.persistSetting ? { persistSetting: deps.persistSetting } : {},
    ...deps.persistSettings ? { persistSettings: deps.persistSettings } : {},
    publishWorkspaceEvent: /* @__PURE__ */ __name((event) => {
      if (event.type === "settings_changed" || event.type === "settings_reloaded") {
        invalidateServeFeaturesCache();
      }
      bridge.publishWorkspaceEvent(event);
    }, "publishWorkspaceEvent")
  });
  const workspaceRegistry = injectedWorkspaceRegistry ?? createSingleWorkspaceRegistry(
    {
      workspaceId: hashDaemonWorkspace(boundWorkspace),
      workspaceCwd: boundWorkspace,
      primary: true,
      trusted: deps.primaryWorkspaceTrusted ?? false,
      env: primaryRuntimeEnvMetadata ?? {
        mode: "parent-process",
        overlayKeys: []
      },
      bridge,
      workspaceService: workspace,
      routeFileSystemFactory: fsFactory,
      clientMcpSenderRegistry
    },
    defaultSessionOwnerIndex ? { sessionOwnerIndex: defaultSessionOwnerIndex } : {}
  );
  app.locals.workspaceRegistry = workspaceRegistry;
  const primaryRuntime = workspaceRegistry.primary;
  const voiceCoordinator = deps.voiceCoordinator ?? new WorkspaceVoiceCoordinator();
  const primaryBoundWorkspace = primaryRuntime.workspaceCwd;
  const primaryBridge = primaryRuntime.bridge;
  const primaryWorkspace = primaryRuntime.workspaceService;
  const primaryRouteFileSystemFactory = primaryRuntime.routeFileSystemFactory;
  const workspaceGitState = new WorkspaceGitState();
  app.locals.stopWorkspaceGitState = () => workspaceGitState.dispose();
  app.locals.stopWorkspaceGitStateForWorkspace = (workspaceCwd) => workspaceGitState.disposeWorkspace(workspaceCwd);
  const workspaceQualifiedAcpEnabled = resolveAcpHttpEnabled();
  if (opts.allowOrigins && opts.allowOrigins.length > 0) {
    const parsedAllowOrigins = parseAllowOriginPatterns(opts.allowOrigins);
    if (parsedAllowOrigins.allowAny && !opts.token) {
      throw new Error(
        `Refusing to start with --allow-origin '*' but no bearer token configured. '*' admits any cross-origin browser to the API; without a token, any local page can drive the daemon. Set a token or list specific origins instead of '*'.`
      );
    }
    app.use(allowOriginCors(parsedAllowOrigins));
  } else {
    app.use(denyBrowserOriginCors);
  }
  app.use(hostAllowlist(opts.hostname, getPort));
  const rateLimiter = installRateLimiter(app, opts, daemonLog, {
    mount: false,
    workspaceQualifiedAcpEnabled
  });
  const healthDemoRoutes = createHealthDemoRoutes({
    opts,
    getPort,
    workspaceRegistry,
    getActiveSseCount,
    getRateLimiter: /* @__PURE__ */ __name(() => rateLimiter, "getRateLimiter")
  });
  if (healthDemoRoutes.exposeHealthPreAuth) {
    healthDemoRoutes.register(app);
  }
  installAccessLogMiddleware(app, daemonLog);
  const webShellDir = opts.serveWebShell !== false ? deps.webShellDir : void 0;
  const webShellFrameAncestors = opts.allowOrigins && opts.allowOrigins.length > 0 ? [...parseAllowOriginPatterns(opts.allowOrigins).origins].filter(
    (o) => o.startsWith("chrome-extension://") || o.startsWith("moz-extension://")
  ) : [];
  if (webShellDir) {
    mountWebShellAssets(app, webShellDir, webShellFrameAncestors);
  }
  if (deps.enqueueChannelWebhookTask) {
    let channelWebhookConfigVersion = -1;
    let channelWebhookConfigs = {};
    const refreshChannelWebhookConfigs = /* @__PURE__ */ __name(() => {
      const version = deps.getChannelWebhookConfigVersion?.() ?? 0;
      try {
        const sources = deps.getChannelWebhookConfigSources?.() ?? (deps.getChannelWorkerControl ? [] : deps.channelWebhookConfigSources ?? [
          { workspaceCwd: primaryBoundWorkspace }
        ]);
        channelWebhookConfigs = loadServeChannelWebhookConfigs(sources);
        channelWebhookConfigVersion = version;
      } catch (error2) {
        channelWebhookConfigs = {};
        daemonLog?.warn(
          `failed to refresh channel webhook configuration: ${error2 instanceof Error ? error2.message : String(error2)}`
        );
      }
    }, "refreshChannelWebhookConfigs");
    deps.registerChannelWebhookConfigRefresh?.(refreshChannelWebhookConfigs);
    registerChannelWebhookRoutes(app, {
      getChannelsConfig: /* @__PURE__ */ __name(() => {
        const version = deps.getChannelWebhookConfigVersion?.() ?? 0;
        if (channelWebhookConfigVersion !== version) {
          refreshChannelWebhookConfigs();
        }
        return channelWebhookConfigs;
      }, "getChannelsConfig"),
      safeBody,
      enqueueWebhookTask: deps.enqueueChannelWebhookTask,
      rateLimiter,
      daemonLog
    });
  }
  app.use(bearerAuth(opts.token));
  if (rateLimiter) {
    app.use(rateLimiter.middleware);
  }
  if (!healthDemoRoutes.exposeHealthPreAuth) {
    healthDemoRoutes.register(app);
  }
  installJsonBodyParser(app);
  const mutate = createMutationGate({
    tokenConfigured,
    requireAuth: opts.requireAuth === true
  });
  app.use(
    daemonTelemetryMiddleware(
      (req) => {
        const match = req.path.match(/^\/workspaces\/([^/]+)/);
        const rawSelector = match?.[1];
        if (rawSelector) {
          try {
            const selector = decodeURIComponent(rawSelector);
            const byId = workspaceRegistry.getByWorkspaceId(selector);
            if (byId) return byId.workspaceCwd;
            if (isPortableAbsolutePath(selector)) {
              const runtime = resolveRegisteredWorkspaceRuntimeByPathSelector(
                workspaceRegistry,
                selector
              );
              if (runtime) return runtime.workspaceCwd;
            }
          } catch {
            return primaryBoundWorkspace;
          }
        }
        return primaryBoundWorkspace;
      },
      deps.recordDaemonRequest,
      (sessionId) => {
        try {
          const owner = workspaceRegistry.resolveLiveSessionOwner(sessionId);
          return owner.kind === "found" ? owner.runtime.workspaceCwd : void 0;
        } catch {
          return void 0;
        }
      }
    )
  );
  const buildWorkspaceCtx = createBuildWorkspaceCtx(primaryBoundWorkspace);
  const acpHandleRef = {};
  const workspaceRememberLane = new WorkspaceRememberTaskLane(
    primaryBridge,
    primaryBoundWorkspace
  );
  const cdpTunnelRegistry = opts.cdpTunnelOverWs === true ? new CdpTunnelRegistry() : void 0;
  registerDaemonStatusRoutes(app, {
    opts,
    boundWorkspace: primaryBoundWorkspace,
    bridge: primaryBridge,
    workspaceRegistry,
    workspace: primaryWorkspace,
    daemonLog,
    startup: deps.startup,
    qwenCodeVersion: deps.qwenCodeVersion,
    getAcpHandle: /* @__PURE__ */ __name(() => acpHandleRef.current, "getAcpHandle"),
    getRateLimiter: /* @__PURE__ */ __name(() => rateLimiter, "getRateLimiter"),
    getRestSseActive: getActiveSseCount,
    currentServeFeatures,
    getSupportedDeviceFlowProviders,
    deviceFlowRegistry,
    sessionShellCommandEnabled,
    getChannelWorkerSnapshot: deps.getChannelWorkerSnapshot,
    getChannelWorkerSnapshots: deps.getChannelWorkerSnapshots,
    getPerfSnapshot: deps.getPerfSnapshot,
    getMetricsSeries: deps.getMetricsSeries,
    getTotalSessionAdmissionSnapshot: deps.getTotalSessionAdmissionSnapshot ?? totalSessionAdmission?.snapshot
  });
  registerCapabilitiesRoutes(app, {
    qwenCodeVersion: deps.qwenCodeVersion,
    mode: opts.mode,
    currentServeFeatures,
    boundWorkspace: primaryBoundWorkspace,
    workspaceRegistry,
    permissionPolicy: primaryBridge.permissionPolicy,
    maxSessionsPerWorkspace: opts.maxSessions,
    maxTotalSessions: opts.maxTotalSessions,
    maxPendingPromptsPerSession: opts.maxPendingPromptsPerSession,
    languageCodes
  });
  registerWorkspaceStatusRoutes(app, {
    boundWorkspace: primaryBoundWorkspace,
    bridge: primaryBridge,
    workspace: primaryWorkspace,
    mutate,
    sendBridgeError: sendBridgeError2
  });
  registerWorkspaceQualifiedStatusRoutes(app, {
    workspaceRegistry,
    sendBridgeError: sendBridgeError2
  });
  registerWorkspaceGitRoutes(app, {
    boundWorkspace: primaryBoundWorkspace,
    bridge: primaryBridge,
    gitState: workspaceGitState,
    sendBridgeError: sendBridgeError2
  });
  registerWorkspaceQualifiedGitRoutes(app, {
    workspaceRegistry,
    gitState: workspaceGitState,
    sendBridgeError: sendBridgeError2
  });
  mountWorkspaceMemoryRoutes(app, {
    bridge: primaryBridge,
    boundWorkspace: primaryBoundWorkspace,
    mutate,
    parseClientId: parseClientIdHeader,
    safeBody
  });
  mountWorkspaceQualifiedMemoryRoutes(app, {
    workspaceRegistry,
    mutate,
    parseClientId: parseClientIdHeader,
    safeBody
  });
  mountWorkspaceMemoryRememberRoutes(app, {
    bridge: primaryBridge,
    lane: workspaceRememberLane,
    mutate,
    parseClientId: parseClientIdHeader,
    safeBody
  });
  mountWorkspaceAgentsRoutes(app, {
    bridge: primaryBridge,
    boundWorkspace: primaryBoundWorkspace,
    mutate,
    parseClientId: parseClientIdHeader,
    safeBody
  });
  mountWorkspaceQualifiedAgentsRoutes(app, {
    workspaceRegistry,
    mutate,
    parseClientId: parseClientIdHeader,
    safeBody
  });
  registerWorkspaceDiagnosticStatusRoutes(app, {
    boundWorkspace: primaryBoundWorkspace,
    bridge: primaryBridge,
    workspace: primaryWorkspace,
    mutate,
    sendBridgeError: sendBridgeError2
  });
  registerWorkspaceQualifiedDiagnosticStatusRoutes(app, {
    workspaceRegistry,
    sendBridgeError: sendBridgeError2
  });
  registerWorkspaceExtensionRoutes(app, {
    boundWorkspace: primaryBoundWorkspace,
    bridge: primaryBridge,
    workspace: primaryWorkspace,
    mutate,
    safeBody,
    sendBridgeError: sendBridgeError2,
    workspaceRegistry,
    ...deps.maxExtensionOperationHistory === void 0 ? {} : { maxExtensionOperationHistory: deps.maxExtensionOperationHistory }
  });
  registerWorkspaceFileReadRoutes(app, {
    parseClientId: parseClientIdHeader
  });
  registerWorkspaceQualifiedFileReadRoutes(app, {
    parseClientId: parseClientIdHeader,
    workspaceRegistry
  });
  registerWorkspaceFileWriteRoutes(app, {
    bridge: primaryBridge,
    mutate,
    parseClientId: parseClientIdHeader,
    safeBody
  });
  registerWorkspaceQualifiedFileWriteRoutes(app, {
    bridge: primaryBridge,
    mutate,
    parseClientId: parseClientIdHeader,
    safeBody,
    workspaceRegistry
  });
  registerWorkspaceSetupGithubRoutes(app, {
    boundWorkspace: primaryBoundWorkspace,
    bridge: primaryBridge,
    mutate,
    parseClientId: parseClientIdHeader,
    safeBody
  });
  registerWorkspaceTrustRoutes(app, {
    boundWorkspace: primaryBoundWorkspace,
    workspace: primaryWorkspace,
    mutate,
    safeBody,
    parseAndValidateClientId: /* @__PURE__ */ __name((req, res) => parseAndValidateWorkspaceClientId(req, res, primaryBridge), "parseAndValidateClientId")
  });
  registerWorkspaceQualifiedTrustRoutes(app, {
    workspaceRegistry,
    mutate,
    safeBody
  });
  const workspaceManagementHandle = registerWorkspaceManagementRoutes(app, {
    workspaceRegistry,
    mutate,
    safeBody,
    createWorkspaceRuntime: deps.createWorkspaceRuntime,
    workspaceRegistrationStore: deps.workspaceRegistrationStore,
    getAcpHandle: /* @__PURE__ */ __name(() => acpHandleRef.current, "getAcpHandle"),
    runtimeRemoval: deps.workspaceRuntimeRemoval
  });
  app.locals.workspaceManagementHandle = workspaceManagementHandle;
  app.locals.workspaceRuntimeRemoval = deps.workspaceRuntimeRemoval;
  const broadcastSettingsChanged = /* @__PURE__ */ __name((key, value, scope, clientId) => {
    invalidateServeFeaturesCache();
    primaryBridge.publishWorkspaceEvent({
      type: "settings_changed",
      data: { key, value, scope },
      ...clientId ? { originatorClientId: clientId } : {}
    });
  }, "broadcastSettingsChanged");
  if (deps.persistSetting) {
    const persistSetting = deps.persistSetting;
    registerWorkspaceSettingsRoutes(app, {
      boundWorkspace: primaryBoundWorkspace,
      mutate,
      safeBody,
      persistSetting: /* @__PURE__ */ __name(async (...args) => {
        await persistSetting(...args);
      }, "persistSetting"),
      broadcastSettingsChanged,
      parseAndValidateClientId: /* @__PURE__ */ __name((req, res) => parseAndValidateWorkspaceClientId(req, res, primaryBridge), "parseAndValidateClientId")
    });
    registerWorkspaceQualifiedSettingsRoutes(app, {
      workspaceRegistry,
      mutate,
      safeBody,
      persistSetting: /* @__PURE__ */ __name(async (...args) => {
        await persistSetting(...args);
      }, "persistSetting"),
      invalidateServeFeaturesCache
    });
  }
  registerWorkspacePermissionsRoutes(app, {
    boundWorkspace: primaryBoundWorkspace,
    mutate,
    safeBody,
    workspace: primaryWorkspace,
    parseAndValidateClientId: /* @__PURE__ */ __name((req, res) => parseAndValidateWorkspaceClientId(req, res, primaryBridge), "parseAndValidateClientId")
  });
  registerWorkspaceQualifiedPermissionsRoutes(app, {
    workspaceRegistry,
    mutate,
    safeBody
  });
  registerWorkspaceVoiceRoutes(app, {
    boundWorkspace: primaryBoundWorkspace,
    mutate,
    safeBody,
    persistSetting: deps.persistSetting,
    persistSettings: deps.persistSettings,
    transcribe: deps.voiceTranscriber,
    env: getRuntimeEffectiveEnv(primaryRuntime.env),
    acquireVoiceLease: /* @__PURE__ */ __name(() => voiceCoordinator.acquire(primaryRuntime), "acquireVoiceLease"),
    broadcastSettingsChanged,
    parseAndValidateClientId: /* @__PURE__ */ __name((req, res) => parseAndValidateWorkspaceClientId(req, res, primaryBridge), "parseAndValidateClientId")
  });
  registerWorkspaceQualifiedVoiceRoutes(app, {
    workspaceRegistry,
    mutate,
    safeBody,
    persistSetting: deps.persistSetting,
    persistSettings: deps.persistSettings,
    transcribe: deps.voiceTranscriber,
    acquireVoiceLease: /* @__PURE__ */ __name((runtime) => voiceCoordinator.acquire(runtime), "acquireVoiceLease"),
    parseAndValidateClientId: /* @__PURE__ */ __name((req, res, runtime) => parseAndValidateWorkspaceClientId(req, res, runtime.bridge), "parseAndValidateClientId"),
    invalidateServeFeaturesCache
  });
  if (deps.persistSettings) {
    registerWorkspaceModelsRoutes(app, {
      boundWorkspace: primaryBoundWorkspace,
      mutate,
      safeBody,
      persistSettings: deps.persistSettings,
      broadcastSettingsChanged,
      parseAndValidateClientId: /* @__PURE__ */ __name((req, res) => parseAndValidateWorkspaceClientId(req, res, primaryBridge), "parseAndValidateClientId")
    });
  }
  registerA2uiActionRoutes(app, {
    boundWorkspace: primaryBoundWorkspace,
    mutate,
    safeBody,
    env: getRuntimeEffectiveEnv(primaryRuntime.env),
    // UI-server discovery uses the daemon's workspace MCP status, which
    // includes servers registered at runtime.
    getMcpServers: /* @__PURE__ */ __name(async () => {
      const ctx = buildWorkspaceCtx("POST /session/:id/a2ui-action");
      const status = await primaryWorkspace.getWorkspaceMcpStatus(ctx);
      return status.servers ?? [];
    }, "getMcpServers")
  });
  registerWorkspaceAuthRoutes(app, {
    mutate,
    deviceFlowRegistry,
    getSupportedDeviceFlowProviders,
    sendBridgeError: sendBridgeError2,
    boundWorkspace: primaryBoundWorkspace,
    allowPrivateAuthBaseUrl: opts.allowPrivateAuthBaseUrl === true,
    installAuthProvider: deps.installAuthProvider
  });
  registerSessionRoutes(app, {
    boundWorkspace: primaryBoundWorkspace,
    bridge: primaryBridge,
    workspaceRegistry,
    archiveCoordinator,
    mutate,
    sendBridgeError: sendBridgeError2,
    daemonLog,
    promptDeadlineMs: opts.promptDeadlineMs,
    sessionShellCommandEnabled,
    languageCodes
  });
  registerWorkspaceMcpControlRoutes(app, {
    boundWorkspace: primaryBoundWorkspace,
    bridge: primaryBridge,
    workspace: primaryWorkspace,
    mutate,
    safeBody,
    sendBridgeError: sendBridgeError2,
    parseAndValidateClientId: /* @__PURE__ */ __name((req, res) => parseAndValidateWorkspaceClientId(req, res, primaryBridge), "parseAndValidateClientId")
  });
  registerWorkspaceQualifiedMcpControlRoutes(app, {
    workspaceRegistry,
    mutate,
    safeBody,
    sendBridgeError: sendBridgeError2
  });
  const channelWorkerControl = deps.getChannelWorkerControl ?? (deps.getChannelWorkerSnapshot ? () => {
    const workers = deps.getChannelWorkerSnapshots?.() ?? [];
    const primary = deps.getChannelWorkerSnapshot();
    return {
      enabled: workers.length > 0 ? workers.some((worker) => worker.enabled) : primary.enabled,
      selection: null,
      transition: "idle",
      workers
    };
  } : void 0);
  if (channelWorkerControl && (deps.reloadChannelWorker || deps.setChannelWorkerSelection && deps.stopChannelWorker)) {
    registerWorkspaceChannelControlRoutes(app, {
      getChannelWorkerControl: channelWorkerControl,
      ...deps.isChannelControlDraining ? { isDaemonDraining: deps.isChannelControlDraining } : {},
      ...deps.isChannelControlInitializing ? { isManagerInitializing: deps.isChannelControlInitializing } : {},
      ...deps.setChannelWorkerSelection ? { setChannelWorkerSelection: deps.setChannelWorkerSelection } : {},
      ...deps.stopChannelWorker ? { stopChannelWorker: deps.stopChannelWorker } : {},
      ...deps.reloadChannelWorker ? { reloadChannelWorker: deps.reloadChannelWorker } : {},
      mutate,
      safeBody,
      sendBridgeError: sendBridgeError2,
      parseAndValidateClientId: /* @__PURE__ */ __name((req, res) => parseAndValidateWorkspaceClientId(req, res, primaryBridge), "parseAndValidateClientId")
    });
  }
  registerWorkspaceLifecycleRoutes(app, {
    boundWorkspace: primaryBoundWorkspace,
    workspace: primaryWorkspace,
    mutate,
    safeBody,
    sendBridgeError: sendBridgeError2,
    invalidateServeFeaturesCache,
    parseAndValidateClientId: /* @__PURE__ */ __name((req, res) => parseAndValidateWorkspaceClientId(req, res, primaryBridge), "parseAndValidateClientId")
  });
  registerWorkspaceQualifiedLifecycleRoutes(app, {
    workspaceRegistry,
    mutate,
    safeBody,
    sendBridgeError: sendBridgeError2,
    invalidateServeFeaturesCache
  });
  registerWorkspaceToolsRoutes(app, {
    boundWorkspace: primaryBoundWorkspace,
    workspace: primaryWorkspace,
    mutate,
    safeBody,
    sendBridgeError: sendBridgeError2,
    parseAndValidateClientId: /* @__PURE__ */ __name((req, res) => parseAndValidateWorkspaceClientId(req, res, primaryBridge), "parseAndValidateClientId")
  });
  registerWorkspaceQualifiedToolsRoutes(app, {
    workspaceRegistry,
    mutate,
    safeBody,
    sendBridgeError: sendBridgeError2
  });
  registerWorkspaceSkillsRoutes(app, {
    workspaceRuntime: primaryRuntime,
    mutate,
    safeBody,
    sendBridgeError: sendBridgeError2,
    parseAndValidateClientId: /* @__PURE__ */ __name((req, res) => parseAndValidateWorkspaceClientId(req, res, primaryBridge), "parseAndValidateClientId")
  });
  registerWorkspaceQualifiedSkillsRoutes(app, {
    workspaceRegistry,
    mutate,
    safeBody,
    sendBridgeError: sendBridgeError2
  });
  registerScheduledTasksRoutes(app, {
    boundWorkspace: primaryBoundWorkspace,
    mutate,
    safeBody,
    bridge: deps.manageScheduledTaskSessions ? bridge : void 0
  });
  registerWorkspaceQualifiedScheduledTasksRoutes(app, {
    workspaceRegistry,
    mutate,
    safeBody,
    manageScheduledTaskSessions: deps.manageScheduledTaskSessions === true
  });
  registerUsageStatsRoutes(app);
  if (deps.manageScheduledTaskSessions) {
    const idleTimeoutMs = opts.sessionIdleTimeoutMs ?? DEFAULT_SESSION_IDLE_TIMEOUT_MS;
    const keepaliveIntervalMs = computeKeepaliveIntervalMs(idleTimeoutMs);
    const rehydrateWorkspace = /* @__PURE__ */ __name((taskBridge, workspaceCwd) => {
      void rehydrateScheduledTaskSessions({
        bridge: taskBridge,
        boundWorkspace: workspaceCwd,
        onError: /* @__PURE__ */ __name((sessionId, err) => {
          process.stderr.write(
            `qwen serve: failed to rehydrate scheduled-task session ${sessionId}: ${err instanceof Error ? err.message : String(err)}
`
          );
        }, "onError")
        // Outer catch is defense-in-depth: rehydrateScheduledTaskSessions already
        // catches readCronTasks failures and per-session load errors internally
        // (returning { loaded, failed }), so this only guards an unexpected throw
        // from the function entry itself. Log rather than swallow it — a silent
        // failure here leaves every bound task dormant with no diagnostic.
      }).catch((err) => {
        process.stderr.write(
          `qwen serve: unexpected scheduled-task rehydration failure: ${err instanceof Error ? err.message : String(err)}
`
        );
      });
    }, "rehydrateWorkspace");
    const keepaliveStops = /* @__PURE__ */ new Map();
    const startKeepaliveForWorkspace = /* @__PURE__ */ __name((runtime) => {
      if (keepaliveStops.has(runtime.workspaceCwd)) return;
      const keepalive = startScheduledTaskKeepalive({
        bridge: runtime.bridge,
        boundWorkspace: runtime.workspaceCwd,
        intervalMs: keepaliveIntervalMs
      });
      rehydrateWorkspace(runtime.bridge, runtime.workspaceCwd);
      keepaliveStops.set(runtime.workspaceCwd, keepalive.stop);
    }, "startKeepaliveForWorkspace");
    for (const runtime of workspaceRegistry.list()) {
      startKeepaliveForWorkspace(runtime);
    }
    app.locals.stopScheduledTaskKeepalive = () => {
      for (const stop of keepaliveStops.values()) stop();
      keepaliveStops.clear();
    };
    app.locals.stopScheduledTaskKeepaliveForWorkspace = (workspaceCwd) => {
      keepaliveStops.get(workspaceCwd)?.();
      keepaliveStops.delete(workspaceCwd);
    };
    app.locals.startScheduledTaskKeepaliveForWorkspace = startKeepaliveForWorkspace;
  }
  registerPermissionRoutes(app, {
    bridge: primaryBridge,
    workspaceRegistry,
    daemonLog,
    mutate,
    sendPermissionVoteError: sendPermissionVoteError2
  });
  registerSseEventsRoutes(app, {
    bridge: primaryBridge,
    workspaceRegistry,
    daemonLog,
    writerIdleTimeoutMs: opts.writerIdleTimeoutMs,
    sendBridgeError: sendBridgeError2
  });
  acpHandleRef.current = mountAcpHttp(app, primaryBridge, {
    boundWorkspace: primaryBoundWorkspace,
    // Phase 4 (issue #6378): pass the registry so `/workspaces/:workspace/acp`
    // mounts a per-runtime ACP dispatcher for each registered workspace.
    workspaceRegistry,
    archiveCoordinator,
    workspace: primaryWorkspace,
    fsFactory: primaryRouteFileSystemFactory,
    deviceFlowRegistry,
    token: opts.token,
    // Mirror the REST CORS allowlist onto the WS CSRF wall so an
    // explicitly permitted origin (e.g. the extension's
    // `chrome-extension://<id>`) can open the reverse tool channel.
    allowedOrigins: opts.allowOrigins && opts.allowOrigins.length > 0 ? parseAllowOriginPatterns(opts.allowOrigins) : void 0,
    hostname: opts.hostname,
    sessionShellCommandEnabled,
    workspaceRememberLane,
    checkRate: rateLimiter?.checkRate,
    clientMcpOverWs: opts.clientMcpOverWs === true,
    // Reverse tool channel (issue #5626, Phase 2). Per-connection provider:
    // on `mcp_register` it records the WS registrar's sender in the shared
    // registry and adds an SDK-type runtime MCP server in the ACP child
    // (originator = the connection id). Only meaningful when
    // `clientMcpOverWs` is on; the WS layer never builds a provider otherwise.
    ...opts.clientMcpOverWs === true ? {
      clientMcpProviderFactory: /* @__PURE__ */ __name((connectionId) => createClientMcpServerProvider(
        primaryRuntime.clientMcpSenderRegistry,
        primaryBridge,
        connectionId
      ), "clientMcpProviderFactory")
    } : {},
    // Plan C CDP tunnel (issue #5626): the `/cdp` branch + `cdp_*` routing
    // activate only when the flag is on and a registry is supplied.
    cdpTunnelOverWs: opts.cdpTunnelOverWs === true,
    ...cdpTunnelRegistry ? { cdpTunnelRegistry } : {},
    // Browser captures audio and streams raw PCM here; the daemon transcribes
    // server-side via the reused CLI voice pipeline. Shares the ACP upgrade
    // listener's loopback/CSRF/bearer checks.
    extraWsRoutes: [
      {
        path: "/voice/stream",
        onConnection: createVoiceWsConnectionHandler(primaryBoundWorkspace, {
          env: getRuntimeEffectiveEnv(primaryRuntime.env),
          acquireVoiceLease: /* @__PURE__ */ __name(() => voiceCoordinator.acquire(primaryRuntime), "acquireVoiceLease")
        })
      }
    ],
    workspaceVoiceConnection: /* @__PURE__ */ __name((runtime, ws, req) => createVoiceWsConnectionHandler(runtime.workspaceCwd, {
      env: getRuntimeEffectiveEnv(runtime.env),
      acquireVoiceLease: /* @__PURE__ */ __name(() => voiceCoordinator.acquire(runtime), "acquireVoiceLease")
    })(ws, req), "workspaceVoiceConnection")
  });
  if (acpHandleRef.current) {
    app.locals["acpHandle"] = acpHandleRef.current;
  }
  if (webShellDir) {
    mountWebShellSpaFallback(app, webShellDir, webShellFrameAncestors);
  }
  installFinalErrorHandler(app);
  if (rateLimiter) {
    setRateLimiter(app, rateLimiter);
  }
  return app;
}
__name(createServeApp, "createServeApp");
export {
  InvalidCursorError,
  PromptDeadlineExceededError,
  computeKeepaliveIntervalMs,
  createDefaultFsAuditEmit,
  createServeApp,
  detectFromLoopback,
  getActiveSseCount,
  listWorkspaceSessionsForResponse,
  resolveBoundWorkspacesFromIdeEnv,
  resolveBridgeFsFactory,
  resolvePromptDeadlineMs
};
/**
 * @license
 * Copyright 2025 Qwen Team
 * SPDX-License-Identifier: Apache-2.0
 */
/**
 * @license
 * Copyright 2026 Qwen Team
 * SPDX-License-Identifier: Apache-2.0
 */
/**
 * @license
 * Copyright 2026 Qwen Team
 * SPDX-License-Identifier: Apache-2.0
 *
 * Reverse link for the Plan C "CDP tunnel" (issue #5626).
 *
 * Bridges a {@link CdpBrowserEmulator} (browser-level CDP to a puppeteer client
 * over `/cdp`) to the Chrome extension's reverse `/acp` WebSocket. Page-domain
 * commands the emulator can't answer are forwarded to the real tab as
 * `cdp_command` frames; the extension runs them and replies with `cdp_result`,
 * and tab `cdp_event`s are re-tagged onto the page session by the emulator.
 *
 * One link is bound to ONE extension `/acp` connection (single daemon = single
 * extension = single browser). The `/acp` WS layer owns the socket and feeds
 * inbound `cdp_*` frames back into the link.
 *
 * See `packages/chrome-extension/docs/06-plan-c-cdp-tunnel.md`.
 */
/**
 * @license
 * Copyright 2026 Qwen Team
 * SPDX-License-Identifier: Apache-2.0
 *
 * CDP browser-level emulation layer for the Plan C "CDP tunnel" (issue #5626).
 *
 * A CDP client connects to the daemon's `/cdp`
 * WebSocket expecting a browser-level CDP endpoint, but behind the tunnel is a
 * single real tab driven via `chrome.debugger` (page-level only). This class
 * synthesizes the missing browser-level topology so puppeteer connects and gets
 * one page:
 *
 *   - a two-level `tab` -> `page` target tree, and
 *   - the recursive `Target.setAutoAttach` handshake puppeteer's
 *     `ExtensionTransport` relies on.
 *
 * Browser-domain commands are answered locally; page-domain commands (tagged
 * with the page session id) are forwarded to the real tab via
 * {@link CdpEmulatorCallbacks.forwardToTab}, and tab events are re-tagged with
 * the page session id on the way back via {@link CdpBrowserEmulator.emitTabEvent}.
 *
 * See `packages/chrome-extension/docs/06-plan-c-cdp-tunnel.md`.
 */
/**
 * @license
 * Copyright 2026 Qwen Team
 * SPDX-License-Identifier: Apache-2.0
 *
 * `/cdp` endpoint glue for the Plan C "CDP tunnel" (issue #5626).
 *
 * Per CDP client connection this wires:
 *
 *   puppeteer  --raw CDP-->  CdpBrowserEmulator  --forwardToTab-->  CdpReverseLink
 *                                                                        |
 *                                            extension `/acp` socket  <--+
 *
 * The emulator answers browser-level CDP locally and forwards page-domain
 * commands to the real tab over the reverse link; tab events flow back. One
 * `/cdp` connection binds to the (single) active extension bridge in the
 * {@link CdpTunnelRegistry}; if no extension is connected the socket is closed
 * immediately with a clear reason.
 *
 * See `packages/chrome-extension/docs/06-plan-c-cdp-tunnel.md`.
 */
/**
 * @license
 * Copyright 2025 Qwen
 * SPDX-License-Identifier: Apache-2.0
 */
/**
 * @license
 * Copyright 2026 Qwen Team
 * SPDX-License-Identifier: Apache-2.0
 *
 * Process-scoped registry pairing the (single) extension `/acp` reverse
 * connection with the `/cdp` endpoint for the Plan C "CDP tunnel" (issue #5626).
 *
 * The `/acp` WS layer registers an outbound `cdp_*` sink here when an extension
 * becomes the active CDP bridge; the `/cdp` endpoint looks it up to build a
 * {@link CdpReverseLink}. Single daemon = single extension = single browser, so
 * at most one bridge is held (last-writer-wins; a reconnect supersedes a stale
 * one). Mirrors `ClientMcpSenderRegistry` so both reverse channels wire the same
 * way through `server.ts`.
 */
