@nextclaw/server 0.14.5 → 0.14.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["isRecord","normalizeOptionalString","MASK_MIN_LENGTH","normalizeOptionalString","maskApiKey","clearSecretRef","isRecord","PANEL_BRIDGE_SESSION_HEADER","isRecord","isRecord","isRecord"],"sources":["../src/features/auth/utils/auth-bridge.utils.ts","../src/shared/utils/http-response.utils.ts","../src/features/auth/controllers/auth.controller.ts","../src/features/auth/utils/access-cookie.utils.ts","../src/features/auth/services/ui-auth.service.ts","../src/features/event-stream/services/event-stream-auth.service.ts","../src/features/event-stream/utils/event-stream-authorizer.utils.ts","../src/features/event-stream/services/event-stream-client-registry.service.ts","../../nextclaw-shared/src/types/typed-key.types.ts","../../nextclaw-shared/src/configs/event-keys.config.ts","../../nextclaw-shared/src/configs/ingress-keys.config.ts","../src/features/agents/stores/agents.store.ts","../src/shared/utils/app-events.utils.ts","../src/features/agents/controllers/agents.controller.ts","../src/app/controllers/app.controller.ts","../src/features/config/utils/extension-channel-config-projection.utils.ts","../src/features/config/utils/channel-auth.utils.ts","../src/features/config/providers/server-builtin-provider.provider.ts","../src/features/config/utils/provider-auth.utils.ts","../src/features/config/controllers/config.controller.ts","../src/features/config/utils/default-provider-config.utils.ts","../src/features/config/utils/runtime-entry-config.utils.ts","../src/features/config/utils/search-config.utils.ts","../src/features/config/stores/server-config.store.ts","../src/features/cron/controllers/cron.controller.ts","../src/features/attachments/controllers/attachments.controller.ts","../src/features/sessions/utils/session-preference-patch.utils.ts","../src/features/sessions/utils/session-project-root.utils.ts","../src/features/marketplace/configs/marketplace.constants.config.ts","../src/features/marketplace/utils/marketplace-network-retry.utils.ts","../src/features/marketplace/utils/marketplace-catalog.utils.ts","../src/features/marketplace/controllers/mcp-marketplace.controller.ts","../src/features/marketplace/utils/marketplace-installed.utils.ts","../src/features/marketplace/controllers/skill-marketplace.controller.ts","../src/features/marketplace/routes/marketplace.route.ts","../src/features/sessions/services/session-skills-view.service.ts","../src/features/sessions/controllers/sessions.controller.ts","../src/features/remote-access/controllers/remote.controller.ts","../src/features/runtime-control/controllers/runtime-control.controller.ts","../src/features/runtime-update/controllers/runtime-update.controller.ts","../src/features/panel-apps/controllers/panel-apps.controller.ts","../src/features/preferences/controllers/preferences.controller.ts","../src/features/service-apps/controllers/service-apps.controller.ts","../src/app/utils/ncp-session-event-stream.utils.ts","../src/features/server-path/utils/server-path-browse.utils.ts","../src/features/server-path/utils/server-path-read.utils.ts","../src/features/server-path/controllers/server-path.controller.ts","../src/app/router.ts","../src/app/server.ts"],"sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { randomBytes } from \"node:crypto\";\nimport { getDataDir } from \"@nextclaw/core\";\n\nconst REMOTE_BRIDGE_DIR = join(getDataDir(), \"remote\");\nconst REMOTE_BRIDGE_SECRET_PATH = join(REMOTE_BRIDGE_DIR, \"ui-bridge-secret\");\n\nexport function getUiBridgeSecretPath(): string {\n return REMOTE_BRIDGE_SECRET_PATH;\n}\n\nexport function readUiBridgeSecret(): string | null {\n if (!existsSync(REMOTE_BRIDGE_SECRET_PATH)) {\n return null;\n }\n try {\n const raw = readFileSync(REMOTE_BRIDGE_SECRET_PATH, \"utf-8\").trim();\n return raw.length > 0 ? raw : null;\n } catch {\n return null;\n }\n}\n\nexport function ensureUiBridgeSecret(): string {\n const existing = readUiBridgeSecret();\n if (existing) {\n return existing;\n }\n mkdirSync(REMOTE_BRIDGE_DIR, { recursive: true });\n const secret = randomBytes(24).toString(\"hex\");\n writeFileSync(REMOTE_BRIDGE_SECRET_PATH, `${secret}\\n`, \"utf-8\");\n return secret;\n}\n","export function ok<T>(data: T) {\n return { ok: true, data };\n}\n\nexport function err(code: string, message: string, details?: Record<string, unknown>) {\n return { ok: false, error: { code, message, details } };\n}\n\nexport async function readJson<T>(req: Request): Promise<{ ok: true; data: T } | { ok: false }> {\n try {\n const data = (await req.json()) as T;\n return { ok: true, data };\n } catch {\n return { ok: false };\n }\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nexport function readErrorMessage(value: unknown, fallback: string): string {\n if (!isRecord(value)) {\n return fallback;\n }\n\n const maybeError = value.error;\n if (!isRecord(maybeError)) {\n return fallback;\n }\n\n return typeof maybeError.message === \"string\" && maybeError.message.trim().length > 0\n ? maybeError.message\n : fallback;\n}\n\nexport function readNonEmptyString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed || undefined;\n}\n\nexport function formatUserFacingError(error: unknown, maxChars = 320): string {\n const raw =\n error instanceof Error ? error.message || error.name || \"Unknown error\" : String(error ?? \"Unknown error\");\n const normalized = raw.replace(/\\s+/g, \" \").trim();\n if (!normalized) {\n return \"Unknown error\";\n }\n if (normalized.length <= maxChars) {\n return normalized;\n }\n return `${normalized.slice(0, Math.max(0, maxChars - 3)).trimEnd()}...`;\n}\n","import type { Context } from \"hono\";\nimport type { UiAuthService } from \"@nextclaw-server/features/auth/index.js\";\nimport { ensureUiBridgeSecret } from \"@nextclaw-server/features/auth/utils/auth-bridge.utils.js\";\nimport type {\n AuthEnabledUpdateRequest,\n AuthLoginRequest,\n AuthPasswordUpdateRequest,\n AuthSetupRequest\n} from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport { err, ok, readJson } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\n\nfunction isAuthenticationRequiredError(message: string): boolean {\n return message === \"Authentication required.\";\n}\n\nfunction isConflictError(message: string): boolean {\n return message.includes(\"already configured\");\n}\n\nfunction setCookieHeader(c: Context, cookie: string | undefined): void {\n if (!cookie) {\n return;\n }\n c.header(\"Set-Cookie\", cookie);\n}\n\nexport class AuthRoutesController {\n constructor(private readonly authService: UiAuthService) {}\n\n readonly getStatus = (c: Context) => {\n return c.json(ok(this.authService.getStatus(c.req.raw)));\n };\n\n readonly setup = async (c: Context) => {\n const body = await readJson<AuthSetupRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n if (typeof body.data.username !== \"string\" || typeof body.data.password !== \"string\") {\n return c.json(err(\"INVALID_BODY\", \"username and password are required\"), 400);\n }\n\n try {\n const result = await this.authService.setup(c.req.raw, body.data);\n setCookieHeader(c, result.cookie);\n return c.json(ok(result.status), 201);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return c.json(err(isConflictError(message) ? \"AUTH_ALREADY_CONFIGURED\" : \"INVALID_BODY\", message), isConflictError(message) ? 409 : 400);\n }\n };\n\n readonly login = async (c: Context) => {\n const body = await readJson<AuthLoginRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n if (typeof body.data.username !== \"string\" || typeof body.data.password !== \"string\") {\n return c.json(err(\"INVALID_BODY\", \"username and password are required\"), 400);\n }\n\n try {\n const result = this.authService.login(c.req.raw, body.data);\n setCookieHeader(c, result.cookie);\n return c.json(ok(result.status));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n const code = message === \"Invalid username or password.\" ? \"INVALID_CREDENTIALS\" : \"AUTH_NOT_ENABLED\";\n const status = message === \"Invalid username or password.\" ? 401 : 400;\n return c.json(err(code, message), status);\n }\n };\n\n readonly logout = (c: Context) => {\n this.authService.logout(c.req.raw);\n setCookieHeader(c, this.authService.buildLogoutCookie(c.req.raw));\n return c.json(ok({ success: true }));\n };\n\n readonly updatePassword = async (c: Context) => {\n const body = await readJson<AuthPasswordUpdateRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n if (typeof body.data.password !== \"string\") {\n return c.json(err(\"INVALID_BODY\", \"password is required\"), 400);\n }\n\n try {\n const result = await this.authService.updatePassword(c.req.raw, body.data);\n setCookieHeader(c, result.cookie);\n return c.json(ok(result.status));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n const status = isAuthenticationRequiredError(message) ? 401 : 400;\n const code = isAuthenticationRequiredError(message) ? \"UNAUTHORIZED\" : \"INVALID_BODY\";\n return c.json(err(code, message), status);\n }\n };\n\n readonly updateEnabled = async (c: Context) => {\n const body = await readJson<AuthEnabledUpdateRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n if (typeof body.data.enabled !== \"boolean\") {\n return c.json(err(\"INVALID_BODY\", \"enabled is required\"), 400);\n }\n\n try {\n const result = await this.authService.updateEnabled(c.req.raw, body.data);\n setCookieHeader(c, result.cookie);\n return c.json(ok(result.status));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n const status = isAuthenticationRequiredError(message) ? 401 : 400;\n const code = isAuthenticationRequiredError(message) ? \"UNAUTHORIZED\" : \"INVALID_BODY\";\n return c.json(err(code, message), status);\n }\n };\n\n readonly issueBridgeSession = (c: Context) => {\n const providedSecret = c.req.header(\"x-nextclaw-ui-bridge-secret\")?.trim();\n const expectedSecret = ensureUiBridgeSecret();\n if (!providedSecret || providedSecret !== expectedSecret) {\n return c.json(err(\"FORBIDDEN\", \"Invalid bridge secret.\"), 403);\n }\n return c.json(ok({\n cookie: this.authService.buildTrustedRequestCookieHeader()\n }));\n };\n}\n","const SESSION_COOKIE_NAME = \"nextclaw_ui_session\";\n\nexport function readAccessSessionTokenFromCookieHeader(rawHeader: string | null | undefined): string | null {\n if (!rawHeader) {\n return null;\n }\n for (const chunk of rawHeader.split(\";\")) {\n const [rawKey, ...rawValue] = chunk.split(\"=\");\n const key = rawKey?.trim();\n if (key === SESSION_COOKIE_NAME) {\n const value = decodeURIComponent(rawValue.join(\"=\").trim());\n return value.trim() ? value.trim() : null;\n }\n }\n return null;\n}\n\nexport function buildAccessLoginCookie(params: {\n token: string;\n secure: boolean;\n expiresAt?: string;\n}): string {\n const { expiresAt, secure, token } = params;\n const parts = [\n `${SESSION_COOKIE_NAME}=${encodeURIComponent(token)}`,\n \"Path=/\",\n \"HttpOnly\",\n \"SameSite=Lax\",\n ];\n if (secure) {\n parts.push(\"Secure\");\n }\n if (expiresAt) {\n const expiresAtMs = Date.parse(expiresAt);\n if (Number.isFinite(expiresAtMs)) {\n const maxAgeSeconds = Math.max(0, Math.trunc((expiresAtMs - Date.now()) / 1000));\n parts.push(`Max-Age=${maxAgeSeconds}`);\n parts.push(`Expires=${new Date(expiresAtMs).toUTCString()}`);\n }\n }\n return parts.join(\"; \");\n}\n\nexport function buildAccessLogoutCookie(secure: boolean): string {\n return [\n `${SESSION_COOKIE_NAME}=`,\n \"Path=/\",\n \"HttpOnly\",\n \"SameSite=Lax\",\n secure ? \"Secure\" : null,\n \"Max-Age=0\",\n `Expires=${new Date(0).toUTCString()}`,\n ].filter((part): part is string => part !== null).join(\"; \");\n}\n\nexport function resolveSecureRequest(url: string, protocolHint?: string | null): boolean {\n if (protocolHint?.trim().toLowerCase() === \"https\") {\n return true;\n }\n try {\n return new URL(url).protocol === \"https:\";\n } catch {\n return false;\n }\n}\n\n","import type { IncomingMessage } from \"node:http\";\nimport type { AccessManager, AccessLoginResult } from \"@nextclaw/kernel\";\nimport type {\n AuthEnabledUpdateRequest,\n AuthLoginRequest,\n AuthPasswordUpdateRequest,\n AuthSetupRequest,\n AuthStatusView,\n} from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport {\n buildAccessLoginCookie,\n buildAccessLogoutCookie,\n readAccessSessionTokenFromCookieHeader,\n resolveSecureRequest,\n} from \"@nextclaw-server/features/auth/utils/access-cookie.utils.js\";\n\nexport class UiAuthService {\n constructor(private readonly accessManager: AccessManager) {}\n\n isProtectionEnabled = (): boolean => this.accessManager.isPasswordProtectionEnabled();\n\n isRequestAuthenticated = (request: Request): boolean => {\n if (!this.isProtectionEnabled()) {\n return true;\n }\n return this.accessManager.authenticateSession(this.readRequestToken(request)) !== null;\n };\n\n isSocketAuthenticated = (request: IncomingMessage): boolean => {\n if (!this.isProtectionEnabled()) {\n return true;\n }\n const rawCookieHeader = Array.isArray(request.headers.cookie)\n ? request.headers.cookie.join(\"; \")\n : request.headers.cookie;\n return this.accessManager.authenticateSession(readAccessSessionTokenFromCookieHeader(rawCookieHeader)) !== null;\n };\n\n getStatus = (request: Request): AuthStatusView => {\n return this.accessManager.getPasswordAuthStatus(this.readRequestToken(request));\n };\n\n setup = async (request: Request, payload: AuthSetupRequest): Promise<{ status: AuthStatusView; cookie: string }> => {\n return this.toCookieResult(request, await this.accessManager.setupPasswordAdmin(payload));\n };\n\n login = (request: Request, payload: AuthLoginRequest): { status: AuthStatusView; cookie: string } => {\n return this.toCookieResult(request, this.accessManager.loginWithPassword(payload));\n };\n\n logout = (request: Request): void => {\n this.accessManager.logout(this.readRequestToken(request));\n };\n\n updatePassword = async (\n request: Request,\n payload: AuthPasswordUpdateRequest,\n ): Promise<{ status: AuthStatusView; cookie?: string }> => {\n return this.toOptionalCookieResult(\n request,\n await this.accessManager.updatePassword({\n token: this.readRequestToken(request),\n password: payload.password,\n }),\n );\n };\n\n updateEnabled = async (\n request: Request,\n payload: AuthEnabledUpdateRequest,\n ): Promise<{ status: AuthStatusView; cookie?: string }> => {\n const result = await this.accessManager.setPasswordAuthEnabled({\n token: this.readRequestToken(request),\n enabled: payload.enabled,\n });\n if (!payload.enabled) {\n return {\n status: result.status,\n cookie: this.buildLogoutCookie(request),\n };\n }\n return this.toOptionalCookieResult(request, result);\n };\n\n buildTrustedRequestCookieHeader = (): string | null => {\n const result = this.accessManager.createTrustedSession();\n return result?.token ? `nextclaw_ui_session=${encodeURIComponent(result.token)}` : null;\n };\n\n buildLogoutCookie = (request: Request): string => {\n return buildAccessLogoutCookie(this.isSecureRequest(request));\n };\n\n private readRequestToken = (request: Request): string | null => {\n return readAccessSessionTokenFromCookieHeader(request.headers.get(\"cookie\"));\n };\n\n private toCookieResult = (\n request: Request,\n result: AccessLoginResult,\n ): { status: AuthStatusView; cookie: string } => {\n if (!result.token) {\n throw new Error(\"Access session token was not created.\");\n }\n return {\n status: result.status,\n cookie: buildAccessLoginCookie({\n token: result.token,\n secure: this.isSecureRequest(request),\n expiresAt: result.expiresAt,\n }),\n };\n };\n\n private toOptionalCookieResult = (\n request: Request,\n result: AccessLoginResult,\n ): { status: AuthStatusView; cookie?: string } => {\n if (!result.token) {\n return {\n status: result.status,\n };\n }\n return this.toCookieResult(request, result);\n };\n\n private isSecureRequest = (request: Request): boolean => {\n return resolveSecureRequest(request.url, request.headers.get(\"x-forwarded-proto\"));\n };\n}\n\n","import type { IncomingMessage } from \"node:http\";\nimport type { ExtensionChannelBinding } from \"@nextclaw/core\";\nimport type { UiAuthService } from \"@nextclaw-server/features/auth/index.js\";\nimport type {\n ExtensionEventStreamAuthenticator,\n EventStreamPrincipal,\n} from \"@nextclaw-server/features/event-stream/types/event-stream-principal.types.js\";\n\nexport type EventStreamAuthServiceDeps = {\n uiAuth: UiAuthService;\n extensionAuth?: ExtensionEventStreamAuthenticator;\n getChannelBindings?: () => ExtensionChannelBinding[];\n};\n\nfunction readHeaderValue(value: string | string[] | undefined): string | null {\n const raw = Array.isArray(value) ? value[0] : value;\n return typeof raw === \"string\" && raw.trim() ? raw.trim() : null;\n}\n\nfunction readBearerToken(value: string | null): string | null {\n if (!value) {\n return null;\n }\n const match = /^Bearer\\s+(.+)$/iu.exec(value);\n return match?.[1]?.trim() || null;\n}\n\nexport class EventStreamAuthService {\n constructor(private readonly deps: EventStreamAuthServiceDeps) {}\n\n authenticate = (request: IncomingMessage): EventStreamPrincipal | null =>\n this.authenticateExtension(request) ?? this.authenticateUi(request);\n\n private readonly authenticateExtension = (request: IncomingMessage): EventStreamPrincipal | null => {\n const token = readBearerToken(readHeaderValue(request.headers.authorization));\n const extensionId = readHeaderValue(request.headers[\"x-nextclaw-extension-id\"]);\n const result = this.deps.extensionAuth?.authenticateEventStreamCredential({\n extensionId,\n token,\n });\n if (!result) {\n return null;\n }\n return {\n principalId: `extension:${result.extensionId}`,\n grants: [\n \"event-stream:extension-requests\",\n \"event-stream:ncp-events\",\n \"event-stream:config-events\",\n ],\n scopes: {\n extensionIds: [result.extensionId],\n channelIds: this.getExtensionChannelIds(result.extensionId),\n },\n };\n };\n\n private readonly authenticateUi = (request: IncomingMessage): EventStreamPrincipal | null => {\n if (!this.deps.uiAuth.isSocketAuthenticated(request)) {\n return null;\n }\n return {\n principalId: \"ui\",\n grants: [\"event-stream:ui-events\"],\n scopes: {},\n };\n };\n\n private readonly getExtensionChannelIds = (extensionId: string): string[] =>\n this.deps.getChannelBindings?.()\n .filter((binding) => binding.extensionId === extensionId)\n .map((binding) => binding.channelId)\n .filter((channelId) => channelId.trim().length > 0) ?? [];\n}\n","import type { AppEventEnvelope } from \"@nextclaw/shared\";\nimport type {\n EventStreamGrant,\n EventStreamPrincipal,\n} from \"@nextclaw-server/features/event-stream/types/event-stream-principal.types.js\";\n\nfunction readRecord(value: unknown): Record<string, unknown> {\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? value as Record<string, unknown>\n : {};\n}\n\nfunction readString(value: unknown): string | null {\n return typeof value === \"string\" && value.trim() ? value.trim() : null;\n}\n\nfunction hasGrant(principal: EventStreamPrincipal, grant: EventStreamGrant): boolean {\n return principal.grants.includes(grant);\n}\n\nfunction scopeValues(principal: EventStreamPrincipal, key: string): string[] {\n const value = principal.scopes[key];\n if (Array.isArray(value)) {\n return value;\n }\n return value ? [value] : [];\n}\n\nfunction hasScopeValue(principal: EventStreamPrincipal, key: string, value: string | null): boolean {\n return Boolean(value && scopeValues(principal, key).includes(value));\n}\n\nfunction readExtensionRequestTarget(event: AppEventEnvelope): string | null {\n return readString(readRecord(event.payload).extensionId);\n}\n\nfunction parseAgentSessionChannel(sessionId: string | null): string | null {\n if (!sessionId) {\n return null;\n }\n const parts = sessionId.split(\":\");\n return parts[0] === \"agent\" && parts.length >= 5 ? readString(parts[2]) : null;\n}\n\nfunction readNcpEventChannel(event: AppEventEnvelope): string | null {\n const payload = readRecord(event.payload);\n const endpointPayload = readRecord(payload.payload);\n const message = readRecord(payload.message ?? endpointPayload.message);\n const metadata = readRecord(message.metadata ?? payload.metadata);\n return (\n readString(metadata.channelId) ??\n readString(metadata.channel) ??\n parseAgentSessionChannel(readString(message.sessionId) ?? readString(payload.sessionId))\n );\n}\n\nexport function canStreamAppEventToPrincipal(\n principal: EventStreamPrincipal,\n event: AppEventEnvelope,\n): boolean {\n if (event.type === \"extension.request\") {\n return hasGrant(principal, \"event-stream:extension-requests\") &&\n hasScopeValue(principal, \"extensionIds\", readExtensionRequestTarget(event));\n }\n\n if (event.type === \"ncp.event\") {\n if (hasGrant(principal, \"event-stream:ui-events\")) {\n return true;\n }\n return hasGrant(principal, \"event-stream:ncp-events\") &&\n hasScopeValue(principal, \"channelIds\", readNcpEventChannel(event));\n }\n\n if (event.type === \"config.updated\") {\n if (hasGrant(principal, \"event-stream:ui-events\")) {\n return true;\n }\n const path = readString(readRecord(event.payload).path);\n const channelId = path?.startsWith(\"channels.\")\n ? path.slice(\"channels.\".length).trim()\n : null;\n return hasGrant(principal, \"event-stream:config-events\") &&\n (path === \"channels\" || hasScopeValue(principal, \"channelIds\", channelId));\n }\n\n return hasGrant(principal, \"event-stream:ui-events\");\n}\n","import type { AppEventEnvelope } from \"@nextclaw/shared\";\nimport { WebSocket } from \"ws\";\nimport type { EventStreamPrincipal } from \"@nextclaw-server/features/event-stream/types/event-stream-principal.types.js\";\nimport { canStreamAppEventToPrincipal } from \"@nextclaw-server/features/event-stream/utils/event-stream-authorizer.utils.js\";\n\ntype EventStreamClient = {\n socket: WebSocket;\n principal: EventStreamPrincipal;\n};\n\nexport class EventStreamClientRegistry {\n private readonly clients = new Set<EventStreamClient>();\n\n add = (socket: WebSocket, principal: EventStreamPrincipal): void => {\n const client = { socket, principal };\n this.clients.add(client);\n socket.on(\"close\", () => this.clients.delete(client));\n };\n\n publish = (event: AppEventEnvelope): void => {\n const payload = JSON.stringify(event);\n for (const client of this.clients) {\n if (\n client.socket.readyState === WebSocket.OPEN &&\n canStreamAppEventToPrincipal(client.principal, event)\n ) {\n client.socket.send(payload);\n }\n }\n };\n\n closeAll = (): void => {\n for (const client of this.clients) {\n client.socket.close();\n }\n this.clients.clear();\n };\n}\n","export type TypedKey<T = unknown> = {\n readonly id: string;\n readonly _type?: T;\n};\n\nexport type Key<T = unknown> = TypedKey<T> | string;\n\nexport function createTypedKey<T>(id: string): TypedKey<T> {\n const normalizedId = id.trim();\n if (!normalizedId) {\n throw new Error(\"typed key id is required\");\n }\n return { id: normalizedId };\n}\n\nexport function getKeyId(key: Key<unknown>): string {\n return typeof key === \"string\" ? key.trim() : key.id;\n}\n","import type { NcpEndpointEvent, NcpSessionSummary } from \"@nextclaw/ncp\";\nimport type { AppEventKey, EventKey } from \"../types/event-bus.types.js\";\nimport { createTypedKey } from \"../types/typed-key.types.js\";\nimport type { UiShowContentEventPayload } from \"../types/ui-show-content.types.js\";\nimport type { UpdateSnapshot } from \"../types/update.types.js\";\n\nexport function createEventKey<T>(id: string): EventKey<T> {\n return createTypedKey<T>(id);\n}\n\nexport function createAppEventKey<T>(id: string): AppEventKey<T> {\n return createTypedKey<T>(id);\n}\n\nexport const eventKeys = {\n configUpdated: createAppEventKey<{ path: string }>(\"config.updated\"),\n channelConfigApplyStatus: createAppEventKey<{\n channel: string;\n status: \"started\" | \"succeeded\" | \"failed\";\n message?: string;\n }>(\"channel.config.apply-status\"),\n sessionUpdated: createAppEventKey<{ sessionKey: string }>(\"session.updated\"),\n sessionRunStatus: createAppEventKey<{\n sessionKey: string;\n status: \"running\" | \"idle\";\n }>(\"session.run-status\"),\n sessionMetadataChanged: createAppEventKey<{\n metadata: Record<string, unknown>;\n mode: \"set\" | \"update\";\n sessionKey: string;\n }>(\"session.metadata.changed\"),\n ncpEvent: createAppEventKey<NcpEndpointEvent>(\"ncp.event\"),\n sessionSummaryUpsert: createAppEventKey<{ summary: NcpSessionSummary }>(\n \"session.summary.upsert\",\n ),\n sessionSummaryDelete: createAppEventKey<{ sessionKey: string }>(\n \"session.summary.delete\",\n ),\n uiShowContent: createAppEventKey<UiShowContentEventPayload>(\"ui.show-content\"),\n configReloadStarted: createAppEventKey<Record<string, unknown> | undefined>(\n \"config.reload.started\",\n ),\n configReloadFinished: createAppEventKey<Record<string, unknown> | undefined>(\n \"config.reload.finished\",\n ),\n error: createAppEventKey<{ message: string; code?: string }>(\"error\"),\n connectionOpen: createAppEventKey<Record<string, never> | undefined>(\n \"connection.open\",\n ),\n connectionClose: createAppEventKey<Record<string, never> | undefined>(\n \"connection.close\",\n ),\n connectionError: createAppEventKey<{ message?: string } | undefined>(\n \"connection.error\",\n ),\n runtimeUpdateSnapshot: createAppEventKey<UpdateSnapshot>(\n \"runtime.update.snapshot\",\n ),\n} as const;\n","import type {\n NcpAgentSendEnvelope,\n NcpMessage,\n NcpMessageAbortPayload,\n NcpMessagePart,\n} from \"@nextclaw/ncp\";\nimport { createTypedKey } from \"../types/typed-key.types.js\";\n\nexport type ExtensionChannelTextContent = {\n type: \"text\";\n text: string;\n};\n\ntype ExtensionChannelResourceRef = {\n url?: string;\n assetUri?: string;\n mimeType?: string;\n name?: string;\n};\n\nexport type ExtensionChannelImageContent = ExtensionChannelResourceRef & { type: \"image\" };\n\nexport type ExtensionChannelFileContent = ExtensionChannelResourceRef & { type: \"file\" };\n\nexport type ExtensionChannelMessageContent =\n | ExtensionChannelTextContent\n | ExtensionChannelImageContent\n | ExtensionChannelFileContent;\n\nexport type ExtensionChannelSubmittedAttachment = ExtensionChannelResourceRef & {\n id?: string;\n path?: string;\n size?: number;\n source?: string;\n status?: \"ready\" | \"remote-only\";\n errorCode?: \"too_large\" | \"download_failed\" | \"http_error\" | \"invalid_payload\";\n};\n\nexport type ExtensionChannelConfigGetIngressPayload = {\n channelId: string;\n};\n\nexport type ExtensionChannelMessageSubmitIngressPayload = {\n channelId: string;\n conversationId: string;\n senderId: string;\n content: ExtensionChannelMessageContent;\n attachments?: ExtensionChannelSubmittedAttachment[];\n metadata?: Record<string, unknown>;\n};\n\nexport type ExtensionChannelCommandOptionType = \"string\" | \"boolean\" | \"number\";\n\nexport type ExtensionChannelCommandOption = {\n name: string;\n description: string;\n type: ExtensionChannelCommandOptionType;\n required?: boolean;\n};\n\nexport type ExtensionChannelCommandSpec = {\n name: string;\n description: string;\n options?: ExtensionChannelCommandOption[];\n};\n\nexport type ExtensionChannelCommandListIngressPayload = {\n channelId: string;\n};\n\nexport type ExtensionChannelCommandListResponse = {\n commands: ExtensionChannelCommandSpec[];\n};\n\nexport type ExtensionChannelCommandExecuteIngressPayload = {\n channelId: string;\n conversationId: string;\n senderId: string;\n commandName?: string;\n rawText?: string;\n args?: Record<string, unknown>;\n metadata?: Record<string, unknown>;\n};\n\nexport type ExtensionChannelCommandExecuteResponse = {\n content: string;\n ephemeral?: boolean;\n};\n\nexport type ExtensionResponseIngressPayload =\n | {\n requestId: string;\n ok: true;\n data?: unknown;\n }\n | {\n requestId: string;\n ok: false;\n error: {\n message: string;\n };\n };\n\nexport type AgentRunSessionMessageRequestPayload = {\n message: NcpMessage;\n requestId: string;\n sessionId: string;\n};\n\nexport type AgentRunSendIngressMetadata = Record<string, unknown> & {\n agentRuntimeId?: string;\n agentId?: string;\n projectRoot?: string;\n channel?: string;\n model?: string;\n maxTokens?: number;\n thinkingEffort?: string | null;\n chatId?: string;\n accountId?: string;\n senderId?: string;\n sessionKey?: string;\n label?: string;\n};\n\nexport type AgentRunSendIngressPayload =\n | (Omit<NcpAgentSendEnvelope, \"metadata\"> & {\n content?: never;\n metadata?: AgentRunSendIngressMetadata;\n peerId?: string;\n })\n | (Omit<NcpAgentSendEnvelope, \"message\" | \"metadata\"> & {\n content: NcpMessagePart[];\n metadata?: AgentRunSendIngressMetadata;\n message?: never;\n peerId?: string;\n });\n\nexport const ingressKeys = {\n extension: {\n channelConfigGet: createTypedKey<ExtensionChannelConfigGetIngressPayload>(\n \"extension.channel.config.get\",\n ),\n channelMessageSubmit:\n createTypedKey<ExtensionChannelMessageSubmitIngressPayload>(\n \"extension.channel.message.submit\",\n ),\n channelCommandList: createTypedKey<ExtensionChannelCommandListIngressPayload>(\n \"extension.channel.command.list\",\n ),\n channelCommandExecute:\n createTypedKey<ExtensionChannelCommandExecuteIngressPayload>(\n \"extension.channel.command.execute\",\n ),\n response: createTypedKey<ExtensionResponseIngressPayload>(\"extension.response\"),\n },\n agentRun: {\n send: createTypedKey<AgentRunSendIngressPayload>(\"agent-run.send\"),\n abort: createTypedKey<NcpMessageAbortPayload>(\"agent-run.abort\"),\n sessionMessageRequest:\n createTypedKey<AgentRunSessionMessageRequestPayload>(\n \"agent-run.session-message.request\",\n ),\n },\n} as const;\n","import {\n createAgentProfile,\n findEffectiveAgentProfile,\n loadConfig,\n readAgentAvatarContent,\n removeAgentProfile,\n resolveEffectiveAgentProfiles,\n updateAgentProfile,\n type Config\n} from \"@nextclaw/core\";\nimport type { AgentCreateRequest, AgentDeleteResult, AgentProfileView, AgentUpdateRequest } from \"@nextclaw-server/shared/types/server-api.types.js\";\n\nexport function listAgents(configPath: string): AgentProfileView[] {\n const config = loadConfig(configPath);\n return resolveEffectiveAgentProfiles(config).map((profile) => toAgentProfileView(config, profile.id));\n}\n\nexport function createAgent(\n configPath: string,\n input: AgentCreateRequest,\n options: { initializeAgentHomeDirectory?: (homeDirectory: string) => void } = {}\n): AgentProfileView {\n const created = createAgentProfile(\n {\n id: input.id,\n displayName: input.displayName,\n description: input.description,\n avatar: input.avatar,\n home: input.home,\n model: input.model,\n runtime: input.runtime,\n runtimeConfig: input.runtimeConfig\n },\n {\n configPath,\n initializeHomeDirectory: options.initializeAgentHomeDirectory\n }\n );\n const config = loadConfig(configPath);\n return toAgentProfileView(config, created.id);\n}\n\nexport function deleteAgent(configPath: string, agentId: string): AgentDeleteResult | null {\n const deleted = removeAgentProfile(agentId, { configPath });\n if (!deleted) {\n return null;\n }\n return {\n deleted: true,\n agentId: agentId.trim().toLowerCase()\n };\n}\n\nexport function updateAgent(configPath: string, agentId: string, input: AgentUpdateRequest): AgentProfileView {\n const updated = updateAgentProfile(\n {\n id: agentId,\n displayName: input.displayName,\n description: input.description,\n avatar: input.avatar,\n model: input.model,\n runtime: input.runtime,\n runtimeConfig: input.runtimeConfig\n },\n { configPath }\n );\n const config = loadConfig(configPath);\n return toAgentProfileView(config, updated.id);\n}\n\nexport function readAgentAvatar(\n configPath: string,\n agentId: string\n): { bytes: Uint8Array; mimeType: string } | null {\n const config = loadConfig(configPath);\n return readAgentAvatarContent({ config, agentId });\n}\n\nexport function toAgentProfileView(config: Config, agentId: string): AgentProfileView {\n const profile = findEffectiveAgentProfile(config, agentId);\n if (!profile) {\n throw new Error(`unknown agent: ${agentId}`);\n }\n return {\n id: profile.id,\n default: profile.default,\n displayName: profile.displayName,\n description: profile.description,\n avatar: profile.avatar,\n avatarUrl: buildAgentAvatarUrl(profile.id, profile.avatar),\n workspace: profile.workspace,\n model: profile.model,\n runtime: profile.runtime,\n runtimeConfig: profile.runtimeConfig,\n engine: profile.engine,\n engineConfig: profile.engineConfig,\n contextTokens: profile.contextTokens,\n maxToolIterations: profile.maxToolIterations,\n builtIn: profile.builtIn === true\n };\n}\n\nexport function buildAgentAvatarUrl(agentId: string, avatar?: string): string | undefined {\n const normalized = typeof avatar === \"string\" ? avatar.trim() : \"\";\n if (!normalized) {\n return undefined;\n }\n if (normalized.startsWith(\"http://\") || normalized.startsWith(\"https://\")) {\n return normalized;\n }\n if (normalized.startsWith(\"home://\")) {\n return `/api/agents/${encodeURIComponent(agentId)}/avatar`;\n }\n return undefined;\n}\n","import { eventKeys } from \"@nextclaw/shared\";\nimport type { UiRouterOptions } from \"@nextclaw-server/app/types/router-options.types.js\";\n\nfunction appEventOptions() {\n return {\n emittedAt: new Date().toISOString(),\n source: \"backend\",\n };\n}\n\nexport function emitConfigUpdated(options: UiRouterOptions, path: string): void {\n options.appEventBus.emit(eventKeys.configUpdated, { path }, appEventOptions());\n}\n\nexport function emitChannelConfigApplyStatus(\n options: UiRouterOptions,\n payload: {\n channel: string;\n status: \"started\" | \"succeeded\" | \"failed\";\n message?: string;\n },\n): void {\n options.appEventBus.emit(eventKeys.channelConfigApplyStatus, payload, appEventOptions());\n}\n\nexport function emitUiError(\n options: UiRouterOptions,\n payload: {\n code?: string;\n message: string;\n },\n): void {\n options.appEventBus.emit(eventKeys.error, payload, appEventOptions());\n}\n","import type { Context } from \"hono\";\nimport { createAgent, deleteAgent, listAgents, readAgentAvatar, updateAgent } from \"@nextclaw-server/features/agents/stores/agents.store.js\";\nimport type { AgentCreateRequest, AgentUpdateRequest } from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport { err, ok, readJson } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport type { UiRouterOptions } from \"@nextclaw-server/app/types/router-options.types.js\";\nimport { emitConfigUpdated } from \"@nextclaw-server/shared/utils/app-events.utils.js\";\n\nexport class AgentsRoutesController {\n constructor(private readonly options: UiRouterOptions) {}\n\n private publishAgentUpdates = async (paths: string[]): Promise<void> => {\n for (const path of paths) {\n emitConfigUpdated(this.options, path);\n }\n await this.options.applyLiveConfigReload?.();\n };\n\n readonly listAgents = (c: Context) => {\n return c.json(ok({ agents: listAgents(this.options.configPath) }));\n };\n\n readonly createAgent = async (c: Context) => {\n const body = await readJson<AgentCreateRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n try {\n const agent = createAgent(this.options.configPath, body.data, {\n initializeAgentHomeDirectory: this.options.initializeAgentHomeDirectory\n });\n await this.publishAgentUpdates([\"agents.list\"]);\n return c.json(ok(agent));\n } catch (error) {\n return c.json(err(\"AGENT_CREATE_FAILED\", error instanceof Error ? error.message : String(error)), 400);\n }\n };\n\n readonly updateAgent = async (c: Context) => {\n const agentId = c.req.param(\"agentId\");\n const body = await readJson<AgentUpdateRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n try {\n const agent = updateAgent(this.options.configPath, agentId, body.data);\n await this.publishAgentUpdates([\"agents.list\"]);\n return c.json(ok(agent));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n const status = message.includes(\"not found\") ? 404 : 400;\n return c.json(err(\"AGENT_UPDATE_FAILED\", message), status);\n }\n };\n\n readonly deleteAgent = async (c: Context) => {\n const agentId = c.req.param(\"agentId\");\n try {\n const result = deleteAgent(this.options.configPath, agentId);\n if (!result) {\n return c.json(err(\"NOT_FOUND\", `agent not found: ${agentId}`), 404);\n }\n await this.publishAgentUpdates([\"agents.list\"]);\n return c.json(ok(result));\n } catch (error) {\n return c.json(err(\"AGENT_DELETE_FAILED\", error instanceof Error ? error.message : String(error)), 400);\n }\n };\n\n readonly getAgentAvatar = (c: Context): Response => {\n const agentId = c.req.param(\"agentId\");\n try {\n const avatar = readAgentAvatar(this.options.configPath, agentId);\n if (!avatar) {\n return c.json(err(\"NOT_FOUND\", `avatar not found for agent: ${agentId}`), 404);\n }\n return new Response(avatar.bytes, {\n headers: {\n \"content-type\": avatar.mimeType,\n \"cache-control\": \"public, max-age=300\"\n }\n });\n } catch (error) {\n return c.json(err(\"AGENT_AVATAR_FAILED\", error instanceof Error ? error.message : String(error)), 400);\n }\n };\n}\n","import type { Context } from \"hono\";\nimport type { AppMetaView, BootstrapStatusView } from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport { ok } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport type { UiRouterOptions } from \"@nextclaw-server/app/types/router-options.types.js\";\n\nfunction buildAppMetaView(options: UiRouterOptions): AppMetaView {\n const productVersion = options.productVersion?.trim();\n return {\n name: \"NextClaw\",\n productVersion: productVersion && productVersion.length > 0 ? productVersion : \"0.0.0\"\n };\n}\n\nfunction buildFallbackBootstrapStatus(): BootstrapStatusView {\n return {\n phase: \"kernel-starting\",\n ncpAgent: {\n state: \"pending\",\n },\n extensionLoading: {\n state: \"pending\",\n loadedExtensionCount: 0,\n totalExtensionCount: 0\n },\n channels: {\n state: \"pending\",\n enabled: []\n },\n remote: {\n state: \"pending\"\n }\n };\n}\n\nexport class AppRoutesController {\n constructor(private readonly options: UiRouterOptions) {}\n\n readonly health = (c: Context) =>\n c.json(\n ok({\n status: \"ok\",\n services: {\n ncpAgent: \"ready\",\n cronService: this.options.cron ? \"ready\" : \"unavailable\"\n }\n })\n );\n\n readonly appMeta = (c: Context) => c.json(ok(buildAppMetaView(this.options)));\n\n readonly bootstrapStatus = (c: Context) =>\n c.json(ok(this.options.bootstrapStatus?.getStatus() ?? buildFallbackBootstrapStatus()));\n}\n","import {\n mergeExtensionConfigView,\n toExtensionConfigView,\n type Config,\n type ConfigUiHints,\n type ExtensionChannelBinding,\n type ExtensionUiMetadata,\n} from \"@nextclaw/core\";\nimport type { ConfigMetaView } from \"@nextclaw-server/shared/types/server-api.types.js\";\n\nexport type ExtensionConfigProjectionOptions = {\n extensionChannelBindings?: ExtensionChannelBinding[];\n extensionUiMetadata?: ExtensionUiMetadata[];\n};\n\ntype ChannelTutorialUrls = NonNullable<ConfigMetaView[\"channels\"][number][\"tutorialUrls\"]>;\nconst DOCS_BASE_URL = \"https://docs.nextclaw.io\";\nconst CHANNEL_TUTORIAL_URLS: Record<string, ChannelTutorialUrls> = {\n feishu: {\n default: `${DOCS_BASE_URL}/guide/tutorials/feishu`,\n en: `${DOCS_BASE_URL}/en/guide/tutorials/feishu`,\n zh: `${DOCS_BASE_URL}/zh/guide/tutorials/feishu`\n },\n weixin: {\n default: \"https://npmx.dev/package/@nextclaw/channel-extension-weixin\"\n }\n};\n\nexport function normalizeExtensionProjectionOptions(options?: ExtensionConfigProjectionOptions): Required<ExtensionConfigProjectionOptions> {\n return {\n extensionChannelBindings: options?.extensionChannelBindings ?? [],\n extensionUiMetadata: options?.extensionUiMetadata ?? []\n };\n}\n\nexport function getProjectedConfigView(config: Config, options?: ExtensionConfigProjectionOptions): Record<string, unknown> {\n normalizeExtensionProjectionOptions(options);\n return toExtensionConfigView(config);\n}\n\nexport function getProjectedChannelMap(\n config: Config,\n options?: ExtensionConfigProjectionOptions\n): Record<string, Record<string, unknown>> {\n const view = getProjectedConfigView(config, options);\n const channels = view.channels;\n if (!channels || typeof channels !== \"object\" || Array.isArray(channels)) {\n return {};\n }\n return channels as Record<string, Record<string, unknown>>;\n}\n\nexport function getProjectedChannelConfig(\n config: Config,\n channelName: string,\n options?: ExtensionConfigProjectionOptions\n): Record<string, unknown> | null {\n const channel = getProjectedChannelMap(config, options)[channelName];\n if (!channel || typeof channel !== \"object\" || Array.isArray(channel)) {\n return null;\n }\n return channel;\n}\n\nexport function buildExtensionChannelUiHints(options?: ExtensionConfigProjectionOptions): ConfigUiHints {\n const normalized = normalizeExtensionProjectionOptions(options);\n if (normalized.extensionChannelBindings.length === 0) {\n return {};\n }\n\n const hints: ConfigUiHints = {};\n const metadataById = new Map(normalized.extensionUiMetadata.map((item) => [item.id, item]));\n\n for (const binding of normalized.extensionChannelBindings) {\n const channelScope = `channels.${binding.channelId}`;\n const channelMeta = binding.channel.meta as Record<string, unknown> | undefined;\n const channelLabel = typeof channelMeta?.selectionLabel === \"string\"\n ? channelMeta.selectionLabel\n : typeof channelMeta?.label === \"string\"\n ? channelMeta.label\n : binding.channelId;\n const channelHelp = typeof channelMeta?.blurb === \"string\" ? channelMeta.blurb : undefined;\n\n hints[channelScope] = {\n ...(channelLabel ? { label: channelLabel } : {}),\n ...(channelHelp ? { help: channelHelp } : {})\n };\n\n const extensionHints = metadataById.get(binding.extensionId)?.configUiHints ?? {};\n for (const [key, hint] of Object.entries(extensionHints)) {\n hints[`${channelScope}.${key}`] = {\n label: hint.label,\n help: hint.help,\n advanced: hint.advanced,\n sensitive: hint.sensitive,\n placeholder: hint.placeholder\n };\n }\n }\n\n return hints;\n}\n\nexport function buildProjectedChannelMeta(\n config: Config,\n options?: ExtensionConfigProjectionOptions\n): ConfigMetaView[\"channels\"] {\n const normalized = normalizeExtensionProjectionOptions(options);\n const projectedChannelMap = getProjectedChannelMap(config, normalized);\n const bindingByChannelId = new Map(normalized.extensionChannelBindings.map((binding) => [binding.channelId, binding]));\n const channelNames = new Set<string>([\n ...Object.keys(config.channels),\n ...Object.keys(projectedChannelMap),\n ...bindingByChannelId.keys()\n ]);\n\n return [...channelNames].map((name) => {\n const tutorialUrls = CHANNEL_TUTORIAL_URLS[name];\n const tutorialUrl = tutorialUrls?.default ?? tutorialUrls?.en ?? tutorialUrls?.zh;\n const binding = bindingByChannelId.get(name);\n const channelMeta = binding?.channel.meta as Record<string, unknown> | undefined;\n const displayName = typeof channelMeta?.selectionLabel === \"string\"\n ? channelMeta.selectionLabel\n : typeof channelMeta?.label === \"string\"\n ? channelMeta.label\n : name;\n\n return {\n name,\n displayName,\n enabled: Boolean(projectedChannelMap[name]?.enabled),\n tutorialUrl,\n tutorialUrls\n };\n });\n}\n\nexport function mergeProjectedExtensionChannelConfig(\n config: Config,\n channelName: string,\n mergedChannel: Record<string, unknown>,\n options?: ExtensionConfigProjectionOptions\n): Config | null {\n const normalized = normalizeExtensionProjectionOptions(options);\n if (!normalized.extensionChannelBindings.some((binding) => binding.channelId === channelName)) {\n return null;\n }\n\n const currentView = getProjectedConfigView(config, normalized);\n const nextView = {\n ...currentView,\n channels: {\n ...((currentView.channels as Record<string, unknown> | undefined) ?? {}),\n [channelName]: mergedChannel\n }\n };\n return mergeExtensionConfigView(config, nextView);\n}\n","import { saveConfig } from \"@nextclaw/core\";\nimport {\n type ExtensionChannelAuthPollResult,\n type ExtensionChannelAuthStartResult,\n type ExtensionChannelBinding\n} from \"@nextclaw/core\";\nimport { loadConfigOrDefault } from \"@nextclaw-server/features/config/index.js\";\nimport { getProjectedConfigView } from \"./extension-channel-config-projection.utils.js\";\nimport type {\n ChannelAuthPollResult,\n ChannelAuthConnectRequest,\n ChannelAuthConnectResult,\n ChannelAuthStartRequest,\n ChannelAuthStartResult\n} from \"@nextclaw-server/shared/types/server-api.types.js\";\n\nfunction cloneChannelConfig(value: unknown): Record<string, unknown> | undefined {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return undefined;\n }\n return JSON.parse(JSON.stringify(value)) as Record<string, unknown>;\n}\n\nfunction findExtensionChannelBinding(bindings: ExtensionChannelBinding[], channelId: string): ExtensionChannelBinding | null {\n const normalizedChannelId = channelId.trim().toLowerCase();\n return bindings.find((binding) => binding.channelId.trim().toLowerCase() === normalizedChannelId) ?? null;\n}\n\nfunction toPublicChannelAuthPollResult(result: ExtensionChannelAuthPollResult): ChannelAuthPollResult {\n return {\n channel: result.channel,\n status: result.status,\n message: result.message,\n nextPollMs: result.nextPollMs,\n accountId: result.accountId,\n notes: result.notes\n };\n}\n\nfunction applyAuthorizedChannelAuthResult(params: {\n configPath: string;\n binding: ExtensionChannelBinding;\n result: ExtensionChannelAuthPollResult;\n}): void {\n const { configPath, binding, result } = params;\n if (result.status !== \"authorized\" || !result.channelConfig) {\n return;\n }\n\n const currentConfig = loadConfigOrDefault(configPath);\n const nextConfig = {\n ...currentConfig,\n channels: {\n ...currentConfig.channels,\n [binding.channelId]: result.channelConfig as typeof currentConfig.channels[keyof typeof currentConfig.channels]\n }\n };\n saveConfig(nextConfig, configPath);\n}\n\nexport async function startChannelAuth(params: {\n configPath: string;\n channelId: string;\n request: ChannelAuthStartRequest;\n bindings: ExtensionChannelBinding[];\n}): Promise<ChannelAuthStartResult | null> {\n const { configPath, channelId, request, bindings } = params;\n const binding = findExtensionChannelBinding(bindings, channelId);\n const start = binding?.channel.auth?.start;\n if (!binding || !start) {\n return null;\n }\n\n const config = loadConfigOrDefault(configPath);\n const configView = getProjectedConfigView(config, {\n extensionChannelBindings: bindings\n }) as typeof config;\n const result = await start({\n cfg: configView,\n extensionId: binding.extensionId,\n channelId: binding.channelId,\n channelConfig: cloneChannelConfig(configView.channels?.[binding.channelId]),\n accountId: request.accountId?.trim() || null,\n baseUrl: request.baseUrl?.trim() || null,\n domain: request.domain?.trim() || null\n });\n\n return result satisfies ExtensionChannelAuthStartResult;\n}\n\nexport async function pollChannelAuth(params: {\n configPath: string;\n channelId: string;\n sessionId: string;\n bindings: ExtensionChannelBinding[];\n}): Promise<ChannelAuthPollResult | null> {\n const { configPath, channelId, sessionId, bindings } = params;\n const binding = findExtensionChannelBinding(bindings, channelId);\n const poll = binding?.channel.auth?.poll;\n if (!binding || !poll) {\n return null;\n }\n\n const config = loadConfigOrDefault(configPath);\n const configView = getProjectedConfigView(config, {\n extensionChannelBindings: bindings\n }) as typeof config;\n const result = await poll({\n cfg: configView,\n extensionId: binding.extensionId,\n channelId: binding.channelId,\n channelConfig: cloneChannelConfig(configView.channels?.[binding.channelId]),\n sessionId\n });\n if (!result) {\n return null;\n }\n\n applyAuthorizedChannelAuthResult({\n configPath,\n binding,\n result\n });\n return toPublicChannelAuthPollResult(result);\n}\n\nexport async function connectChannelAuth(params: {\n configPath: string;\n channelId: string;\n request: ChannelAuthConnectRequest;\n bindings: ExtensionChannelBinding[];\n}): Promise<ChannelAuthConnectResult | null> {\n const { configPath, channelId, request, bindings } = params;\n const binding = findExtensionChannelBinding(bindings, channelId);\n const connect = binding?.channel.auth?.connect;\n if (!binding || !connect) {\n return null;\n }\n\n const config = loadConfigOrDefault(configPath);\n const configView = getProjectedConfigView(config, {\n extensionChannelBindings: bindings\n }) as typeof config;\n const result = await connect({\n cfg: configView,\n extensionId: binding.extensionId,\n channelId: binding.channelId,\n channelConfig: cloneChannelConfig(configView.channels?.[binding.channelId]),\n accountId: request.accountId?.trim() || null,\n domain: request.domain?.trim() || null,\n fields: request.fields\n });\n\n applyAuthorizedChannelAuthResult({\n configPath,\n binding,\n result\n });\n return toPublicChannelAuthPollResult(result);\n}\n","import type { ProviderSpec } from '@nextclaw/core';\nimport { findBuiltinProviderByName, listBuiltinProviders } from '@nextclaw/runtime';\n\nconst MINIMAX_PORTAL_PROVIDER_SPEC: ProviderSpec = {\n name: 'minimax-portal',\n keywords: ['minimax-portal', 'minimax'],\n envKey: 'MINIMAX_PORTAL_TOKEN',\n displayName: 'MiniMax Portal',\n modelPrefix: 'minimax-portal',\n litellmPrefix: 'minimax-portal',\n skipPrefixes: ['minimax-portal/'],\n envExtras: [],\n isGateway: false,\n isLocal: false,\n detectByKeyPrefix: '',\n detectByBaseKeyword: '',\n defaultApiBase: 'https://api.minimax.io/v1',\n defaultModels: ['minimax-portal/MiniMax-M3', 'minimax-portal/MiniMax-M2.5', 'minimax-portal/MiniMax-M2.5-highspeed'],\n modelConfig: { 'minimax-portal/MiniMax-M3': { vision: true } },\n stripModelPrefix: false,\n modelOverrides: [],\n logo: 'minimax.svg',\n apiBaseHelp: {\n zh: 'OAuth Global 默认使用 https://api.minimax.io/v1;OAuth 中国区默认使用 https://api.minimaxi.com/v1。',\n en: 'OAuth Global uses https://api.minimax.io/v1 by default; OAuth CN uses https://api.minimaxi.com/v1.'\n },\n auth: {\n kind: 'device_code',\n protocol: 'minimax_user_code',\n displayName: 'MiniMax OAuth',\n baseUrl: 'https://api.minimax.io',\n deviceCodePath: '/oauth/code',\n tokenPath: '/oauth/token',\n clientId: '78257093-7e40-4613-99e0-527b14b39113',\n scope: 'group_id profile model.completion',\n grantType: 'urn:ietf:params:oauth:grant-type:user_code',\n usePkce: true,\n defaultMethodId: 'cn',\n methods: [\n {\n id: 'global',\n label: {\n zh: 'Global(海外)',\n en: 'Global'\n },\n hint: {\n zh: '适用于海外用户,默认 API Base 为 https://api.minimax.io/v1。',\n en: 'For international users. Default API base: https://api.minimax.io/v1.'\n },\n baseUrl: 'https://api.minimax.io',\n defaultApiBase: 'https://api.minimax.io/v1'\n },\n {\n id: 'cn',\n label: {\n zh: '中国区(CN)',\n en: 'China Mainland (CN)'\n },\n hint: {\n zh: '适用于中国区用户,默认 API Base 为 https://api.minimaxi.com/v1。',\n en: 'For Mainland China users. Default API base: https://api.minimaxi.com/v1.'\n },\n baseUrl: 'https://api.minimaxi.com',\n defaultApiBase: 'https://api.minimaxi.com/v1'\n }\n ],\n note: {\n zh: '通过浏览器完成 MiniMax OAuth 授权后即可使用,无需手动填写 API Key。',\n en: 'Complete MiniMax OAuth in browser to use this provider without manually entering an API key.'\n }\n }\n};\n\nconst SERVER_BUILTIN_PROVIDER_OVERRIDES: ProviderSpec[] = [MINIMAX_PORTAL_PROVIDER_SPEC];\nconst SERVER_BUILTIN_PROVIDER_OVERRIDE_MAP = new Map(SERVER_BUILTIN_PROVIDER_OVERRIDES.map((provider) => [provider.name, provider] as const));\n\nexport function listServerBuiltinProviders(): ProviderSpec[] {\n const merged = new Map<string, ProviderSpec>();\n for (const provider of listBuiltinProviders()) {\n merged.set(provider.name, provider);\n }\n for (const provider of SERVER_BUILTIN_PROVIDER_OVERRIDES) {\n merged.set(provider.name, provider);\n }\n return Array.from(merged.values());\n}\n\nexport function findServerBuiltinProviderByName(name: string): ProviderSpec | undefined {\n return SERVER_BUILTIN_PROVIDER_OVERRIDE_MAP.get(name) ?? findBuiltinProviderByName(name);\n}\n","import { createHash, randomBytes, randomUUID } from \"node:crypto\";\nimport { readFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { isAbsolute, resolve } from \"node:path\";\nimport {\n ConfigSchema,\n loadConfig,\n saveConfig,\n type ProviderConfig,\n type ProviderDeviceCodeAuthMethodSpec,\n type ProviderDeviceCodeAuthProtocol,\n type ProviderDeviceCodeAuthSpec\n} from \"@nextclaw/core\";\nimport type { ProviderAuthImportResult, ProviderAuthPollResult, ProviderAuthStartResult } from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport { findServerBuiltinProviderByName } from \"@nextclaw-server/features/config/providers/server-builtin-provider.provider.js\";\n\ntype DeviceCodeSession = {\n sessionId: string;\n providerId: string;\n providerType: string;\n configPath: string;\n authorizationCode: string;\n tokenCodeField: \"device_code\" | \"user_code\";\n protocol: ProviderDeviceCodeAuthProtocol;\n methodId?: string;\n codeVerifier?: string;\n tokenEndpoint: string;\n clientId: string;\n grantType: string;\n defaultApiBase?: string;\n expiresAtMs: number;\n intervalMs: number;\n};\n\ntype DeviceCodePayload = {\n device_code?: string;\n user_code?: string;\n verification_uri?: string;\n verification_uri_complete?: string;\n interval?: number;\n expires_in?: number;\n error?: string;\n error_description?: string;\n};\n\ntype MiniMaxCodePayload = {\n user_code?: string;\n verification_uri?: string;\n expired_in?: number;\n interval?: number;\n state?: string;\n base_resp?: {\n status_code?: number;\n status_msg?: string;\n };\n};\n\ntype TokenPayload = {\n access_token?: string;\n refresh_token?: string;\n expires_in?: number;\n error?: string;\n error_description?: string;\n};\n\ntype MiniMaxTokenPayload = {\n status?: string;\n access_token?: string | null;\n refresh_token?: string | null;\n expired_in?: number | null;\n base_resp?: {\n status_code?: number;\n status_msg?: string;\n };\n};\n\ntype ResolvedAuthMethod = {\n id?: string;\n protocol: ProviderDeviceCodeAuthProtocol;\n baseUrl: string;\n deviceCodePath: string;\n tokenPath: string;\n clientId: string;\n scope: string;\n grantType: string;\n usePkce: boolean;\n defaultApiBase?: string;\n};\n\nconst authSessions = new Map<string, DeviceCodeSession>();\nconst DEFAULT_AUTH_INTERVAL_MS = 2000;\nconst MAX_AUTH_INTERVAL_MS = 10000;\n\nfunction normalizePositiveInt(value: unknown, fallback: number): number {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value <= 0) {\n return fallback;\n }\n return Math.floor(value);\n}\n\nfunction normalizePositiveFloat(value: unknown): number | null {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value <= 0) {\n return null;\n }\n return value;\n}\n\nfunction toBase64Url(buffer: Buffer): string {\n return buffer.toString(\"base64\").replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/g, \"\");\n}\n\nfunction buildPkce(): { verifier: string; challenge: string } {\n const verifier = toBase64Url(randomBytes(48));\n const challenge = toBase64Url(createHash(\"sha256\").update(verifier).digest());\n return { verifier, challenge };\n}\n\nfunction withTrailingSlash(value: string): string {\n return value.endsWith(\"/\") ? value : `${value}/`;\n}\n\nfunction cleanupExpiredAuthSessions(now = Date.now()): void {\n for (const [sessionId, session] of authSessions.entries()) {\n if (session.expiresAtMs <= now) {\n authSessions.delete(sessionId);\n }\n }\n}\n\nfunction resolveDeviceCodeEndpoints(baseUrl: string, deviceCodePath: string, tokenPath: string): {\n deviceCodeEndpoint: string;\n tokenEndpoint: string;\n} {\n const deviceCodeEndpoint = new URL(deviceCodePath, withTrailingSlash(baseUrl)).toString();\n const tokenEndpoint = new URL(tokenPath, withTrailingSlash(baseUrl)).toString();\n return { deviceCodeEndpoint, tokenEndpoint };\n}\n\nfunction resolveAuthNote(params: {\n zh?: string;\n en?: string;\n}): string | undefined {\n return params.zh ?? params.en;\n}\n\nfunction resolveLocalizedMethodLabel(\n method: ProviderDeviceCodeAuthMethodSpec,\n fallbackId: string\n): string | undefined {\n return method.label?.zh ?? method.label?.en ?? fallbackId;\n}\n\nfunction resolveLocalizedMethodHint(method: ProviderDeviceCodeAuthMethodSpec): string | undefined {\n return method.hint?.zh ?? method.hint?.en;\n}\n\nfunction normalizeMethodId(value: string | undefined): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction resolveAuthMethod(auth: ProviderDeviceCodeAuthSpec, requestedMethodId?: string): ResolvedAuthMethod {\n const protocol = auth.protocol ?? \"rfc8628\";\n const methods = (auth.methods ?? []).filter((entry) => normalizeMethodId(entry.id));\n const cleanRequestedMethodId = normalizeMethodId(requestedMethodId);\n\n if (methods.length === 0) {\n if (cleanRequestedMethodId) {\n throw new Error(`provider auth method is not supported: ${cleanRequestedMethodId}`);\n }\n return {\n protocol,\n baseUrl: auth.baseUrl,\n deviceCodePath: auth.deviceCodePath,\n tokenPath: auth.tokenPath,\n clientId: auth.clientId,\n scope: auth.scope,\n grantType: auth.grantType,\n usePkce: Boolean(auth.usePkce)\n };\n }\n\n let selectedMethod = methods.find((entry) => normalizeMethodId(entry.id) === cleanRequestedMethodId);\n if (!selectedMethod) {\n const fallbackMethodId = normalizeMethodId(auth.defaultMethodId) ?? normalizeMethodId(methods[0]?.id);\n selectedMethod = methods.find((entry) => normalizeMethodId(entry.id) === fallbackMethodId) ?? methods[0];\n }\n const methodId = normalizeMethodId(selectedMethod?.id);\n if (!selectedMethod || !methodId) {\n throw new Error(\"provider auth method is not configured\");\n }\n if (cleanRequestedMethodId && methodId !== cleanRequestedMethodId) {\n throw new Error(`provider auth method is not supported: ${cleanRequestedMethodId}`);\n }\n\n return {\n id: methodId,\n protocol,\n baseUrl: selectedMethod.baseUrl ?? auth.baseUrl,\n deviceCodePath: selectedMethod.deviceCodePath ?? auth.deviceCodePath,\n tokenPath: selectedMethod.tokenPath ?? auth.tokenPath,\n clientId: selectedMethod.clientId ?? auth.clientId,\n scope: selectedMethod.scope ?? auth.scope,\n grantType: selectedMethod.grantType ?? auth.grantType,\n usePkce: selectedMethod.usePkce ?? Boolean(auth.usePkce),\n defaultApiBase: selectedMethod.defaultApiBase\n };\n}\n\nfunction parseExpiresAtMs(\n value: unknown,\n fallbackFromNowMs: number\n): number {\n const normalized = normalizePositiveFloat(value);\n if (normalized === null) {\n return Date.now() + fallbackFromNowMs;\n }\n if (normalized >= 1_000_000_000_000) {\n return Math.floor(normalized);\n }\n if (normalized >= 1_000_000_000) {\n return Math.floor(normalized * 1000);\n }\n return Date.now() + Math.floor(normalized * 1000);\n}\n\nfunction parsePollIntervalMs(value: unknown, fallbackMs: number): number {\n const normalized = normalizePositiveFloat(value);\n if (normalized === null) {\n return fallbackMs;\n }\n if (normalized <= 30) {\n return Math.floor(normalized * 1000);\n }\n return Math.floor(normalized);\n}\n\nfunction buildMinimaxErrorMessage(payload: unknown, fallback: string): string {\n if (!payload || typeof payload !== \"object\" || Array.isArray(payload)) {\n return fallback;\n }\n const record = payload as {\n base_resp?: { status_msg?: unknown };\n error?: unknown;\n error_description?: unknown;\n };\n if (typeof record.error_description === \"string\" && record.error_description.trim()) {\n return record.error_description.trim();\n }\n if (typeof record.error === \"string\" && record.error.trim()) {\n return record.error.trim();\n }\n const baseMessage = record.base_resp?.status_msg;\n if (typeof baseMessage === \"string\" && baseMessage.trim()) {\n return baseMessage.trim();\n }\n return fallback;\n}\n\nfunction classifyMiniMaxErrorStatus(message: string): \"denied\" | \"expired\" | \"error\" {\n const normalized = message.toLowerCase();\n if (normalized.includes(\"deny\") || normalized.includes(\"rejected\")) {\n return \"denied\";\n }\n if (normalized.includes(\"expired\") || normalized.includes(\"timeout\") || normalized.includes(\"timed out\")) {\n return \"expired\";\n }\n return \"error\";\n}\n\nfunction resolveHomePath(inputPath: string): string {\n const trimmed = inputPath.trim();\n if (!trimmed) {\n return trimmed;\n }\n if (trimmed === \"~\") {\n return homedir();\n }\n if (trimmed.startsWith(\"~/\")) {\n return resolve(homedir(), trimmed.slice(2));\n }\n if (isAbsolute(trimmed)) {\n return trimmed;\n }\n return resolve(trimmed);\n}\n\nfunction normalizeExpiresAt(value: unknown): number | null {\n if (typeof value === \"number\" && Number.isFinite(value) && value > 0) {\n return Math.floor(value);\n }\n if (typeof value === \"string\" && value.trim()) {\n const asNumber = Number(value);\n if (Number.isFinite(asNumber) && asNumber > 0) {\n return Math.floor(asNumber);\n }\n const parsedTime = Date.parse(value);\n if (Number.isFinite(parsedTime) && parsedTime > 0) {\n return parsedTime;\n }\n }\n return null;\n}\n\nfunction readFieldAsString(source: Record<string, unknown>, fieldName: string | undefined): string | null {\n if (!fieldName) {\n return null;\n }\n const rawValue = source[fieldName];\n if (typeof rawValue !== \"string\") {\n return null;\n }\n const trimmed = rawValue.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction setProviderApiKey({ configPath, provider, accessToken, defaultApiBase }: {\n configPath: string;\n provider: string;\n accessToken: string;\n defaultApiBase?: string;\n}): void {\n const config = loadConfig(configPath);\n const providers = config.providers as Record<string, ProviderConfig>;\n if (!providers[provider]) {\n return;\n }\n\n const target = providers[provider];\n target.apiKey = accessToken;\n if (defaultApiBase) {\n target.apiBase = defaultApiBase;\n }\n const next = ConfigSchema.parse(config);\n saveConfig(next, configPath);\n}\n\nfunction resolveProviderAuthTarget(configPath: string, providerId: string): {\n providerId: string;\n providerType: string;\n provider: ProviderConfig;\n} | null {\n const config = loadConfig(configPath);\n const provider = (config.providers as Record<string, ProviderConfig>)[providerId];\n if (!provider) {\n return null;\n }\n const configuredType = typeof provider.providerType === \"string\" ? provider.providerType.trim() : \"\";\n if (configuredType && findServerBuiltinProviderByName(configuredType)) {\n return { providerId, providerType: configuredType, provider };\n }\n if (findServerBuiltinProviderByName(providerId)) {\n return { providerId, providerType: providerId, provider };\n }\n return null;\n}\n\nexport async function startProviderAuth(\n configPath: string,\n providerId: string,\n options?: {\n methodId?: string;\n }\n): Promise<ProviderAuthStartResult | null> {\n cleanupExpiredAuthSessions();\n\n const target = resolveProviderAuthTarget(configPath, providerId);\n if (!target) {\n return null;\n }\n const spec = findServerBuiltinProviderByName(target.providerType);\n if (!spec?.auth || spec.auth.kind !== \"device_code\") {\n return null;\n }\n const resolvedMethod = resolveAuthMethod(spec.auth, options?.methodId);\n\n const { deviceCodeEndpoint, tokenEndpoint } = resolveDeviceCodeEndpoints(\n resolvedMethod.baseUrl,\n resolvedMethod.deviceCodePath,\n resolvedMethod.tokenPath\n );\n const pkce = resolvedMethod.usePkce ? buildPkce() : null;\n\n let authorizationCode = \"\";\n let tokenCodeField: \"device_code\" | \"user_code\" = \"device_code\";\n let userCode = \"\";\n let verificationUri = \"\";\n let intervalMs = DEFAULT_AUTH_INTERVAL_MS;\n let expiresAtMs = Date.now() + 600_000;\n\n if (resolvedMethod.protocol === \"minimax_user_code\") {\n if (!pkce) {\n throw new Error(\"MiniMax OAuth requires PKCE\");\n }\n const state = toBase64Url(randomBytes(16));\n const body = new URLSearchParams({\n response_type: \"code\",\n client_id: resolvedMethod.clientId,\n scope: resolvedMethod.scope,\n code_challenge: pkce.challenge,\n code_challenge_method: \"S256\",\n state\n });\n const response = await fetch(deviceCodeEndpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\",\n \"x-request-id\": randomUUID()\n },\n body\n });\n const payload = (await response.json().catch(() => ({}))) as MiniMaxCodePayload;\n if (!response.ok) {\n throw new Error(buildMinimaxErrorMessage(payload, response.statusText || \"MiniMax OAuth start failed\"));\n }\n if (payload.state && payload.state !== state) {\n throw new Error(\"MiniMax OAuth state mismatch\");\n }\n authorizationCode = payload.user_code?.trim() ?? \"\";\n userCode = authorizationCode;\n verificationUri = payload.verification_uri?.trim() ?? \"\";\n if (!authorizationCode || !verificationUri) {\n throw new Error(\"provider auth payload is incomplete\");\n }\n tokenCodeField = \"user_code\";\n intervalMs = Math.min(parsePollIntervalMs(payload.interval, DEFAULT_AUTH_INTERVAL_MS), MAX_AUTH_INTERVAL_MS);\n expiresAtMs = parseExpiresAtMs(payload.expired_in, 600_000);\n } else {\n const body = new URLSearchParams({\n client_id: resolvedMethod.clientId,\n scope: resolvedMethod.scope\n });\n if (pkce) {\n body.set(\"code_challenge\", pkce.challenge);\n body.set(\"code_challenge_method\", \"S256\");\n }\n const response = await fetch(deviceCodeEndpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\"\n },\n body\n });\n const payload = (await response.json().catch(() => ({}))) as DeviceCodePayload;\n if (!response.ok) {\n const message = payload.error_description || payload.error || response.statusText || \"device code auth failed\";\n throw new Error(message);\n }\n\n authorizationCode = payload.device_code?.trim() ?? \"\";\n userCode = payload.user_code?.trim() ?? \"\";\n verificationUri = payload.verification_uri_complete?.trim() || payload.verification_uri?.trim() || \"\";\n\n if (!authorizationCode || !userCode || !verificationUri) {\n throw new Error(\"provider auth payload is incomplete\");\n }\n\n intervalMs = normalizePositiveInt(payload.interval, DEFAULT_AUTH_INTERVAL_MS / 1000) * 1000;\n const expiresInSec = normalizePositiveInt(payload.expires_in, 600);\n expiresAtMs = Date.now() + expiresInSec * 1000;\n }\n\n const sessionId = randomUUID();\n\n authSessions.set(sessionId, {\n sessionId,\n providerId,\n providerType: target.providerType,\n configPath,\n authorizationCode,\n tokenCodeField,\n protocol: resolvedMethod.protocol,\n methodId: resolvedMethod.id,\n codeVerifier: pkce?.verifier,\n tokenEndpoint,\n clientId: resolvedMethod.clientId,\n grantType: resolvedMethod.grantType,\n defaultApiBase: resolvedMethod.defaultApiBase ?? spec.defaultApiBase,\n expiresAtMs,\n intervalMs\n });\n\n const methodConfig = (spec.auth.methods ?? []).find((entry) => normalizeMethodId(entry.id) === resolvedMethod.id);\n const methodLabel = methodConfig ? resolveLocalizedMethodLabel(methodConfig, resolvedMethod.id ?? \"\") : undefined;\n const methodHint = methodConfig ? resolveLocalizedMethodHint(methodConfig) : undefined;\n\n return {\n provider: providerId,\n kind: \"device_code\",\n methodId: resolvedMethod.id,\n sessionId,\n verificationUri,\n userCode,\n expiresAt: new Date(expiresAtMs).toISOString(),\n intervalMs,\n note: methodHint ?? methodLabel ?? resolveAuthNote(spec.auth.note ?? {})\n };\n}\n\nexport async function pollProviderAuth(params: {\n configPath: string;\n providerName: string;\n sessionId: string;\n}): Promise<ProviderAuthPollResult | null> {\n const { configPath, providerName: providerId, sessionId } = params;\n cleanupExpiredAuthSessions();\n\n const session = authSessions.get(sessionId);\n if (!session || session.providerId !== providerId || session.configPath !== configPath) {\n return null;\n }\n\n if (Date.now() >= session.expiresAtMs) {\n authSessions.delete(sessionId);\n return {\n provider: providerId,\n status: \"expired\",\n message: \"authorization session expired\"\n };\n }\n\n const body = new URLSearchParams({\n grant_type: session.grantType,\n client_id: session.clientId\n });\n body.set(session.tokenCodeField, session.authorizationCode);\n if (session.codeVerifier) {\n body.set(\"code_verifier\", session.codeVerifier);\n }\n\n const response = await fetch(session.tokenEndpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\"\n },\n body\n });\n let accessToken = \"\";\n\n if (session.protocol === \"minimax_user_code\") {\n const raw = await response.text();\n let payload: MiniMaxTokenPayload = {};\n if (raw) {\n try {\n payload = JSON.parse(raw) as MiniMaxTokenPayload;\n } catch {\n payload = {};\n }\n }\n if (!response.ok) {\n const message = buildMinimaxErrorMessage(payload, raw || response.statusText || \"authorization failed\");\n return {\n provider: providerId,\n status: \"error\",\n message\n };\n }\n\n const status = payload.status?.trim().toLowerCase();\n if (status === \"success\") {\n accessToken = payload.access_token?.trim() ?? \"\";\n if (!accessToken) {\n return {\n provider: providerId,\n status: \"error\",\n message: \"provider token response missing access token\"\n };\n }\n } else if (status === \"error\") {\n const message = buildMinimaxErrorMessage(payload, \"authorization failed\");\n const classified = classifyMiniMaxErrorStatus(message);\n if (classified === \"denied\" || classified === \"expired\") {\n authSessions.delete(sessionId);\n }\n return {\n provider: providerId,\n status: classified,\n message\n };\n } else {\n const nextPollMs = Math.min(Math.floor(session.intervalMs * 1.5), MAX_AUTH_INTERVAL_MS);\n session.intervalMs = nextPollMs;\n authSessions.set(sessionId, session);\n return {\n provider: providerId,\n status: \"pending\",\n nextPollMs\n };\n }\n } else {\n const payload = (await response.json().catch(() => ({}))) as TokenPayload;\n if (!response.ok) {\n const errorCode = payload.error?.trim().toLowerCase();\n if (errorCode === \"authorization_pending\") {\n return {\n provider: providerId,\n status: \"pending\",\n nextPollMs: session.intervalMs\n };\n }\n\n if (errorCode === \"slow_down\") {\n const nextPollMs = Math.min(Math.floor(session.intervalMs * 1.5), MAX_AUTH_INTERVAL_MS);\n session.intervalMs = nextPollMs;\n authSessions.set(sessionId, session);\n return {\n provider: providerId,\n status: \"pending\",\n nextPollMs\n };\n }\n\n if (errorCode === \"access_denied\") {\n authSessions.delete(sessionId);\n return {\n provider: providerId,\n status: \"denied\",\n message: payload.error_description || \"authorization denied\"\n };\n }\n\n if (errorCode === \"expired_token\") {\n authSessions.delete(sessionId);\n return {\n provider: providerId,\n status: \"expired\",\n message: payload.error_description || \"authorization session expired\"\n };\n }\n\n return {\n provider: providerId,\n status: \"error\",\n message: payload.error_description || payload.error || response.statusText || \"authorization failed\"\n };\n }\n\n accessToken = payload.access_token?.trim() ?? \"\";\n if (!accessToken) {\n return {\n provider: providerId,\n status: \"error\",\n message: \"provider token response missing access token\"\n };\n }\n }\n\n setProviderApiKey({\n configPath,\n provider: providerId,\n accessToken,\n defaultApiBase: session.defaultApiBase\n });\n\n authSessions.delete(sessionId);\n return {\n provider: providerId,\n status: \"authorized\"\n };\n}\n\nexport async function importProviderAuthFromCli(\n configPath: string,\n providerId: string\n): Promise<ProviderAuthImportResult | null> {\n const target = resolveProviderAuthTarget(configPath, providerId);\n if (!target) {\n return null;\n }\n const spec = findServerBuiltinProviderByName(target.providerType);\n if (!spec?.auth || spec.auth.kind !== \"device_code\" || !spec.auth.cliCredential) {\n return null;\n }\n\n const credentialPath = resolveHomePath(spec.auth.cliCredential.path);\n if (!credentialPath) {\n throw new Error(\"provider cli credential path is empty\");\n }\n\n let rawContent = \"\";\n try {\n rawContent = await readFile(credentialPath, \"utf8\");\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`failed to read CLI credential: ${message}`);\n }\n\n let payload: Record<string, unknown>;\n try {\n const parsed = JSON.parse(rawContent) as unknown;\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new Error(\"credential payload is not an object\");\n }\n payload = parsed as Record<string, unknown>;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`invalid CLI credential JSON: ${message}`);\n }\n\n const accessToken = readFieldAsString(payload, spec.auth.cliCredential.accessTokenField);\n if (!accessToken) {\n throw new Error(\n `CLI credential missing access token field: ${spec.auth.cliCredential.accessTokenField}`\n );\n }\n\n const expiresAtMs = normalizeExpiresAt(\n spec.auth.cliCredential.expiresAtField\n ? payload[spec.auth.cliCredential.expiresAtField]\n : undefined\n );\n if (typeof expiresAtMs === \"number\" && expiresAtMs <= Date.now()) {\n throw new Error(\"CLI credential has expired, please login again\");\n }\n\n setProviderApiKey({\n configPath,\n provider: providerId,\n accessToken,\n defaultApiBase: spec.defaultApiBase\n });\n\n return {\n provider: providerId,\n status: \"imported\",\n source: \"cli\",\n expiresAt: expiresAtMs ? new Date(expiresAtMs).toISOString() : undefined\n };\n}\n","import type { Context } from \"hono\";\nimport {\n buildConfigSchemaView,\n buildConfigMeta,\n buildConfigView,\n buildProvidersView,\n buildProviderTemplatesView,\n loadConfigOrDefault,\n executeConfigAction,\n updateChannel,\n updateModel,\n updateSearch,\n createProvider,\n deleteProvider,\n updateProvider,\n testProviderConnection,\n updateSecrets,\n updateRuntime\n} from \"@nextclaw-server/features/config/index.js\";\nimport { connectChannelAuth, pollChannelAuth, startChannelAuth } from \"@nextclaw-server/features/config/utils/channel-auth.utils.js\";\nimport { importProviderAuthFromCli, pollProviderAuth, startProviderAuth } from \"@nextclaw-server/features/config/utils/provider-auth.utils.js\";\nimport type {\n ChannelAuthPollResult,\n ChannelAuthConnectRequest,\n ChannelAuthConnectResult,\n ChannelAuthStartRequest,\n ChannelAuthStartResult,\n ConfigActionExecuteRequest,\n ProviderConnectionTestRequest,\n ProviderAuthStartRequest,\n ProviderAuthPollResult,\n ProviderAuthImportResult,\n ProviderAuthStartResult,\n ProviderCreateRequest,\n ProviderCreateResult,\n ProviderDeleteResult,\n ProviderConfigUpdate,\n SearchConfigUpdate,\n SecretsConfigUpdate,\n RuntimeConfigUpdate\n} from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport { err, ok, readJson } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport type { UiRouterOptions } from \"@nextclaw-server/app/types/router-options.types.js\";\nimport { emitChannelConfigApplyStatus, emitConfigUpdated, emitUiError } from \"@nextclaw-server/shared/utils/app-events.utils.js\";\n\nexport class ConfigRoutesController {\n private readonly channelConfigApplyTasks = new Map<string, Promise<void>>();\n\n constructor(private readonly options: UiRouterOptions) {}\n\n private readonly getExtensionConfigProjectionOptions = () => {\n return {\n extensionChannelBindings: this.options.extensions?.getChannelBindings() ?? [],\n extensionUiMetadata: this.options.extensions?.getUiMetadata() ?? []\n };\n };\n\n private readonly publishConfigUpdatedPaths = (paths: string[]): void => {\n for (const path of paths) {\n emitConfigUpdated(this.options, path);\n }\n };\n\n private readonly publishConfigUpdates = async (paths: string[]): Promise<void> => {\n this.publishConfigUpdatedPaths(paths);\n await this.options.applyLiveConfigReload?.();\n };\n\n private readonly publishChannelConfigApplyStatus = (params: {\n channel: string;\n status: \"started\" | \"succeeded\" | \"failed\";\n message?: string;\n }): void => {\n emitChannelConfigApplyStatus(this.options, params);\n };\n\n private readonly enqueueChannelConfigApply = (channel: string): void => {\n const previousTask = this.channelConfigApplyTasks.get(channel) ?? Promise.resolve();\n const task = previousTask\n .catch(() => undefined)\n .then(async () => {\n this.publishChannelConfigApplyStatus({\n channel,\n status: \"started\"\n });\n try {\n await this.options.applyLiveConfigReload?.();\n this.publishChannelConfigApplyStatus({\n channel,\n status: \"succeeded\"\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n this.publishChannelConfigApplyStatus({\n channel,\n status: \"failed\",\n message\n });\n emitUiError(this.options, {\n code: \"CHANNEL_CONFIG_APPLY_FAILED\",\n message: `Failed to apply ${channel} channel config: ${message}`\n });\n }\n })\n .finally(() => {\n if (this.channelConfigApplyTasks.get(channel) === task) {\n this.channelConfigApplyTasks.delete(channel);\n }\n });\n\n this.channelConfigApplyTasks.set(channel, task);\n void task;\n };\n\n readonly getConfig = (c: Context) => {\n const config = loadConfigOrDefault(this.options.configPath);\n return c.json(ok(buildConfigView(config, this.getExtensionConfigProjectionOptions())));\n };\n\n readonly getConfigMeta = (c: Context) => {\n const config = loadConfigOrDefault(this.options.configPath);\n return c.json(ok(buildConfigMeta(config, this.getExtensionConfigProjectionOptions())));\n };\n\n readonly listProviders = (c: Context) => {\n const config = loadConfigOrDefault(this.options.configPath);\n return c.json(ok(buildProvidersView(config)));\n };\n\n readonly listProviderTemplates = (c: Context) => {\n return c.json(ok(buildProviderTemplatesView()));\n };\n\n readonly getConfigSchema = (c: Context) => {\n const config = loadConfigOrDefault(this.options.configPath);\n return c.json(ok(buildConfigSchemaView(config, this.getExtensionConfigProjectionOptions())));\n };\n\n readonly updateConfigModel = async (c: Context) => {\n const body = await readJson<{ model?: string; workspace?: string }>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n\n const hasModel = typeof body.data.model === \"string\";\n if (!hasModel) {\n return c.json(err(\"INVALID_BODY\", \"model is required\"), 400);\n }\n\n const view = updateModel(this.options.configPath, {\n model: body.data.model,\n workspace: body.data.workspace\n });\n\n const changedPaths: string[] = [];\n if (hasModel) {\n changedPaths.push(\"agents.defaults.model\");\n }\n if (typeof body.data.workspace === \"string\") {\n changedPaths.push(\"agents.defaults.workspace\");\n }\n await this.publishConfigUpdates(changedPaths);\n\n return c.json(ok({\n model: view.agents.defaults.model,\n workspace: view.agents.defaults.workspace\n }));\n };\n\n readonly updateConfigSearch = async (c: Context) => {\n const body = await readJson<Record<string, unknown>>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n const result = updateSearch(this.options.configPath, body.data as SearchConfigUpdate);\n await this.publishConfigUpdates([\"search\"]);\n return c.json(ok(result));\n };\n\n readonly updateProvider = async (c: Context) => {\n const providerId = c.req.param(\"providerId\");\n const body = await readJson<Record<string, unknown>>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n const result = updateProvider(this.options.configPath, providerId, body.data as ProviderConfigUpdate);\n if (!result) {\n return c.json(err(\"NOT_FOUND\", `unknown provider: ${providerId}`), 404);\n }\n await this.publishConfigUpdates([`providers.${providerId}`]);\n return c.json(ok(result));\n };\n\n readonly createProvider = async (c: Context) => {\n const body = await readJson<Record<string, unknown>>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n const result = createProvider(\n this.options.configPath,\n body.data as ProviderCreateRequest\n );\n if (!result) {\n return c.json(err(\"PROVIDER_EXISTS\", \"provider already exists\"), 409);\n }\n await this.publishConfigUpdates([`providers.${result.providerId}`]);\n return c.json(ok({\n providerId: result.providerId,\n provider: result.provider\n } satisfies ProviderCreateResult));\n };\n\n readonly deleteProvider = async (c: Context) => {\n const providerId = c.req.param(\"providerId\");\n const result = deleteProvider(this.options.configPath, providerId);\n if (result === null) {\n return c.json(err(\"NOT_FOUND\", `provider not found: ${providerId}`), 404);\n }\n await this.publishConfigUpdates([`providers.${providerId}`]);\n return c.json(ok({\n deleted: true,\n providerId\n } satisfies ProviderDeleteResult));\n };\n\n readonly testProviderConnection = async (c: Context) => {\n const provider = c.req.param(\"providerId\");\n const body = await readJson<Record<string, unknown>>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n const result = await testProviderConnection(\n this.options.configPath,\n provider,\n body.data as ProviderConnectionTestRequest,\n this.options.kernel.llmProviders\n );\n if (!result) {\n return c.json(err(\"NOT_FOUND\", `unknown provider: ${provider}`), 404);\n }\n return c.json(ok(result));\n };\n\n readonly startProviderAuth = async (c: Context) => {\n const provider = c.req.param(\"providerId\");\n let payload: Record<string, unknown> = {};\n const rawBody = await c.req.raw.text();\n if (rawBody.trim().length > 0) {\n try {\n payload = JSON.parse(rawBody) as Record<string, unknown>;\n } catch {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n }\n const methodId = typeof payload.methodId === \"string\"\n ? payload.methodId.trim()\n : undefined;\n try {\n const result = await startProviderAuth(this.options.configPath, provider, {\n methodId\n } satisfies ProviderAuthStartRequest);\n if (!result) {\n return c.json(err(\"NOT_SUPPORTED\", `provider auth is not supported: ${provider}`), 404);\n }\n return c.json(ok(result satisfies ProviderAuthStartResult));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return c.json(err(\"AUTH_START_FAILED\", message), 400);\n }\n };\n\n readonly pollProviderAuth = async (c: Context) => {\n const provider = c.req.param(\"providerId\");\n const body = await readJson<Record<string, unknown>>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n const sessionId = typeof body.data.sessionId === \"string\" ? body.data.sessionId.trim() : \"\";\n if (!sessionId) {\n return c.json(err(\"INVALID_BODY\", \"sessionId is required\"), 400);\n }\n\n const result = await pollProviderAuth({\n configPath: this.options.configPath,\n providerName: provider,\n sessionId\n });\n if (!result) {\n return c.json(err(\"NOT_FOUND\", \"provider auth session not found\"), 404);\n }\n if (result.status === \"authorized\") {\n await this.publishConfigUpdates([`providers.${provider}`]);\n }\n return c.json(ok(result satisfies ProviderAuthPollResult));\n };\n\n readonly importProviderAuthFromCli = async (c: Context) => {\n const provider = c.req.param(\"providerId\");\n try {\n const result = await importProviderAuthFromCli(this.options.configPath, provider);\n if (!result) {\n return c.json(err(\"NOT_SUPPORTED\", `provider cli auth import is not supported: ${provider}`), 404);\n }\n await this.publishConfigUpdates([`providers.${provider}`]);\n return c.json(ok(result satisfies ProviderAuthImportResult));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return c.json(err(\"AUTH_IMPORT_FAILED\", message), 400);\n }\n };\n\n readonly updateChannel = async (c: Context) => {\n const channel = c.req.param(\"channel\");\n const body = await readJson<Record<string, unknown>>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n const result = updateChannel(this.options.configPath, channel, body.data, this.getExtensionConfigProjectionOptions());\n if (!result) {\n return c.json(err(\"NOT_FOUND\", `unknown channel: ${channel}`), 404);\n }\n this.publishConfigUpdatedPaths([`channels.${channel}`]);\n this.enqueueChannelConfigApply(channel);\n return c.json(ok(result));\n };\n\n readonly startChannelAuth = async (c: Context) => {\n const channel = c.req.param(\"channel\");\n let payload: Record<string, unknown> = {};\n const rawBody = await c.req.raw.text();\n if (rawBody.trim().length > 0) {\n try {\n payload = JSON.parse(rawBody) as Record<string, unknown>;\n } catch {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n }\n\n try {\n const result = await startChannelAuth({\n configPath: this.options.configPath,\n channelId: channel,\n request: {\n accountId: typeof payload.accountId === \"string\" ? payload.accountId : undefined,\n baseUrl: typeof payload.baseUrl === \"string\" ? payload.baseUrl : undefined,\n domain: typeof payload.domain === \"string\" ? payload.domain : undefined\n } satisfies ChannelAuthStartRequest,\n bindings: this.options.extensions?.getChannelBindings() ?? []\n });\n if (!result) {\n return c.json(err(\"NOT_SUPPORTED\", `channel auth is not supported: ${channel}`), 404);\n }\n return c.json(ok(result satisfies ChannelAuthStartResult));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return c.json(err(\"AUTH_START_FAILED\", message), 400);\n }\n };\n\n readonly pollChannelAuth = async (c: Context) => {\n const channel = c.req.param(\"channel\");\n const body = await readJson<Record<string, unknown>>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n const sessionId = typeof body.data.sessionId === \"string\" ? body.data.sessionId.trim() : \"\";\n if (!sessionId) {\n return c.json(err(\"INVALID_BODY\", \"sessionId is required\"), 400);\n }\n\n const result = await pollChannelAuth({\n configPath: this.options.configPath,\n channelId: channel,\n sessionId,\n bindings: this.options.extensions?.getChannelBindings() ?? []\n });\n if (!result) {\n return c.json(err(\"NOT_FOUND\", \"channel auth session not found\"), 404);\n }\n if (result.status === \"authorized\") {\n await this.publishConfigUpdates([`channels.${channel}`]);\n }\n return c.json(ok(result satisfies ChannelAuthPollResult));\n };\n\n readonly connectChannelAuth = async (c: Context) => {\n const channel = c.req.param(\"channel\");\n const body = await readJson<Record<string, unknown>>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n const fields = body.data.fields && typeof body.data.fields === \"object\" && !Array.isArray(body.data.fields)\n ? body.data.fields as Record<string, unknown>\n : {};\n\n try {\n const result = await connectChannelAuth({\n configPath: this.options.configPath,\n channelId: channel,\n request: {\n accountId: typeof body.data.accountId === \"string\" ? body.data.accountId : undefined,\n domain: typeof body.data.domain === \"string\" ? body.data.domain : undefined,\n fields\n } satisfies ChannelAuthConnectRequest,\n bindings: this.options.extensions?.getChannelBindings() ?? []\n });\n if (!result) {\n return c.json(err(\"NOT_SUPPORTED\", `channel auth connect is not supported: ${channel}`), 404);\n }\n if (result.status === \"authorized\") {\n await this.publishConfigUpdates([`channels.${channel}`]);\n }\n return c.json(ok(result satisfies ChannelAuthConnectResult));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return c.json(err(\"AUTH_CONNECT_FAILED\", message), 400);\n }\n };\n\n readonly updateSecrets = async (c: Context) => {\n const body = await readJson<Record<string, unknown>>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n const result = updateSecrets(this.options.configPath, body.data as SecretsConfigUpdate);\n await this.publishConfigUpdates([\"secrets\"]);\n return c.json(ok(result));\n };\n\n readonly updateRuntime = async (c: Context) => {\n const body = await readJson<RuntimeConfigUpdate>(c.req.raw);\n if (!body.ok || !body.data || typeof body.data !== \"object\") {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n const result = updateRuntime(this.options.configPath, body.data);\n const changedPaths: string[] = [];\n if (body.data.agents?.defaults && Object.prototype.hasOwnProperty.call(body.data.agents.defaults, \"contextTokens\")) {\n changedPaths.push(\"agents.defaults.contextTokens\");\n }\n if (body.data.agents?.defaults && Object.prototype.hasOwnProperty.call(body.data.agents.defaults, \"engine\")) {\n changedPaths.push(\"agents.defaults.engine\");\n }\n if (body.data.agents?.defaults && Object.prototype.hasOwnProperty.call(body.data.agents.defaults, \"engineConfig\")) {\n changedPaths.push(\"agents.defaults.engineConfig\");\n }\n if (body.data.agents?.runtimes && Object.prototype.hasOwnProperty.call(body.data.agents.runtimes, \"entries\")) {\n changedPaths.push(\"agents.runtimes.entries\");\n }\n if (body.data.companion && Object.prototype.hasOwnProperty.call(body.data.companion, \"enabled\")) {\n changedPaths.push(\"companion.enabled\");\n }\n changedPaths.push(\"agents.list\", \"bindings\", \"session\");\n await this.publishConfigUpdates(changedPaths);\n return c.json(ok(result));\n };\n\n readonly executeAction = async (c: Context) => {\n const actionId = c.req.param(\"actionId\");\n const body = await readJson<ConfigActionExecuteRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n const result = await executeConfigAction(this.options.configPath, actionId, body.data ?? {});\n if (!result.ok) {\n return c.json(err(result.code, result.message, result.details), 400);\n }\n return c.json(ok(result.data));\n };\n}\n","import { normalizeProviderModelConfig, type ProviderConfig, type ProviderSpec } from \"@nextclaw/core\";\n\nexport function createDefaultProviderConfig(\n defaultWireApi: \"auto\" | \"chat\" | \"responses\" = \"auto\",\n defaultModels: string[] = [],\n modelConfig: ProviderConfig[\"modelConfig\"] = {},\n providerType?: string | null,\n defaultApiBase: string | null = null\n): ProviderConfig {\n return {\n enabled: true,\n providerType,\n displayName: \"\",\n apiKey: \"\",\n apiBase: defaultApiBase,\n extraHeaders: null,\n wireApi: defaultWireApi,\n models: [...defaultModels],\n modelConfig\n };\n}\n\nexport function createDefaultProviderConfigFromSpec(spec: ProviderSpec | undefined): ProviderConfig {\n return createDefaultProviderConfig(\n spec?.defaultWireApi ?? \"auto\",\n spec?.defaultModels ?? [],\n normalizeProviderModelConfig(spec?.modelConfig ?? {}),\n spec?.name,\n spec?.defaultApiBase ?? null\n );\n}\n","import { normalizeModelThinkingCapability } from \"@nextclaw/core\";\n\nfunction normalizeOptionalString(value: unknown): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction normalizePositiveInteger(value: unknown): number | null {\n const parsed =\n typeof value === \"number\"\n ? value\n : typeof value === \"string\"\n ? Number.parseInt(value, 10)\n : Number.NaN;\n if (!Number.isFinite(parsed)) {\n return null;\n }\n const normalized = Math.trunc(parsed);\n return normalized > 0 ? normalized : null;\n}\n\nfunction normalizeStringArray(value: unknown): string[] | null {\n if (!Array.isArray(value)) {\n return null;\n }\n const entries = value\n .map((entry) => normalizeOptionalString(entry))\n .filter((entry): entry is string => Boolean(entry));\n return entries.length > 0 ? entries : null;\n}\n\nfunction normalizeUnknownStringRecord(value: unknown): Record<string, string> | null {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return null;\n }\n const entries = Object.entries(value)\n .map(([key, entryValue]) => [key.trim(), normalizeOptionalString(entryValue)] as const)\n .filter(([key, entryValue]) => key.length > 0 && Boolean(entryValue));\n return entries.length > 0 ? Object.fromEntries(entries) as Record<string, string> : null;\n}\n\nfunction normalizeRuntimeModelSelectionMode(value: unknown): string | null {\n if (value === \"nextclaw\" || value === \"optional\" || value === \"runtime-default\") {\n return value;\n }\n return null;\n}\n\nexport function normalizeRuntimeEntryConfig(\n type: string,\n config: Record<string, unknown>,\n): Record<string, unknown> {\n const runtimeDefaultThinking = normalizeModelThinkingCapability(config.runtimeDefaultThinking);\n if (type !== \"narp-stdio\") {\n const restConfig = Object.fromEntries(\n Object.entries(config).filter(([key]) => key !== \"runtimeDefaultThinking\"),\n );\n return {\n ...restConfig,\n ...(runtimeDefaultThinking ? { runtimeDefaultThinking } : {}),\n };\n }\n\n const command = normalizeOptionalString(config.command);\n const args = normalizeStringArray(config.args);\n const cwd = normalizeOptionalString(config.cwd);\n const wireDialect = normalizeOptionalString(config.wireDialect) ?? \"acp\";\n const processScope = normalizeOptionalString(config.processScope) ?? \"per-session\";\n const modelSelectionMode = normalizeRuntimeModelSelectionMode(config.modelSelectionMode);\n const supportedModels = normalizeStringArray(config.supportedModels);\n const resetSessionMetadataOnPromptTimeout = normalizeStringArray(\n config.resetSessionMetadataOnPromptTimeout,\n );\n const model = normalizeOptionalString(config.model);\n const recommendedModel = normalizeOptionalString(config.recommendedModel);\n\n return {\n wireDialect,\n processScope,\n ...(command ? { command } : {}),\n ...(args ? { args } : {}),\n env: normalizeUnknownStringRecord(config.env) ?? {},\n ...(cwd ? { cwd } : {}),\n ...(modelSelectionMode ? { modelSelectionMode } : {}),\n ...(model ? { model } : {}),\n ...(recommendedModel ? { recommendedModel } : {}),\n ...(supportedModels ? { supportedModels } : {}),\n ...(runtimeDefaultThinking ? { runtimeDefaultThinking } : {}),\n ...(resetSessionMetadataOnPromptTimeout\n ? { resetSessionMetadataOnPromptTimeout }\n : {}),\n startupTimeoutMs: normalizePositiveInteger(config.startupTimeoutMs) ?? 8000,\n probeTimeoutMs: normalizePositiveInteger(config.probeTimeoutMs) ?? 3000,\n requestTimeoutMs: normalizePositiveInteger(config.requestTimeoutMs) ?? 120000,\n };\n}\n","import {\n ConfigSchema,\n hasSecretRef,\n loadConfig,\n saveConfig,\n type Config,\n type SearchConfig\n} from \"@nextclaw/core\";\nimport type {\n BochaFreshnessValue,\n ConfigMetaView,\n ConfigView,\n SearchConfigUpdate,\n SearchProviderName,\n TavilySearchDepthValue\n} from \"@nextclaw-server/shared/types/server-api.types.js\";\n\nconst MASK_MIN_LENGTH = 8;\nconst BOCHA_OPEN_URL = \"https://open.bocha.cn\";\nconst TAVILY_DOCS_URL = \"https://docs.tavily.com/documentation/api-reference/endpoint/search\";\nconst SEARCH_PROVIDER_NAMES = [\"bocha\", \"tavily\", \"brave\"] as const;\ntype BochaSearchPatch = NonNullable<NonNullable<SearchConfigUpdate[\"providers\"]>[\"bocha\"]>;\ntype TavilySearchPatch = NonNullable<NonNullable<SearchConfigUpdate[\"providers\"]>[\"tavily\"]>;\ntype BraveSearchPatch = NonNullable<NonNullable<SearchConfigUpdate[\"providers\"]>[\"brave\"]>;\n\nfunction normalizeOptionalString(value: unknown): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction maskApiKey(value: string): { apiKeySet: boolean; apiKeyMasked?: string } {\n if (!value) {\n return { apiKeySet: false };\n }\n if (value.length < MASK_MIN_LENGTH) {\n return { apiKeySet: true, apiKeyMasked: \"****\" };\n }\n return {\n apiKeySet: true,\n apiKeyMasked: `${value.slice(0, 2)}****${value.slice(-4)}`\n };\n}\n\nfunction clearSecretRef(refs: Config[\"secrets\"][\"refs\"], path: string): Config[\"secrets\"][\"refs\"] {\n if (!refs[path]) {\n return refs;\n }\n const nextRefs = { ...refs };\n delete nextRefs[path];\n return nextRefs;\n}\n\nfunction isSearchProviderName(value: unknown): value is SearchProviderName {\n return typeof value === \"string\" && SEARCH_PROVIDER_NAMES.some((providerName) => providerName === value);\n}\n\nexport const SEARCH_PROVIDER_META: ConfigMetaView[\"search\"] = [\n {\n name: \"bocha\",\n displayName: \"Bocha Search\",\n description: \"China-friendly web search with AI-ready summaries.\",\n docsUrl: BOCHA_OPEN_URL,\n isDefault: true,\n supportsSummary: true\n },\n {\n name: \"tavily\",\n displayName: \"Tavily Search\",\n description: \"Research-focused web search with optional synthesized answers.\",\n docsUrl: TAVILY_DOCS_URL,\n supportsSummary: true\n },\n {\n name: \"brave\",\n displayName: \"Brave Search\",\n description: \"Brave web search API kept as an optional provider.\",\n supportsSummary: false\n }\n];\n\nfunction toSearchProviderView(\n config: Config,\n providerName: SearchProviderName,\n provider: SearchConfig[\"providers\"][SearchProviderName]\n): ConfigView[\"search\"][\"providers\"][\"bocha\"] {\n const apiKeyPath = `search.providers.${providerName}.apiKey`;\n const apiKeyRefSet = hasSecretRef(config, apiKeyPath);\n const masked = maskApiKey(provider.apiKey);\n const view: ConfigView[\"search\"][\"providers\"][\"bocha\"] = {\n enabled: config.search.enabledProviders.includes(providerName),\n apiKeySet: masked.apiKeySet || apiKeyRefSet,\n apiKeyMasked: masked.apiKeyMasked ?? (apiKeyRefSet ? \"****\" : undefined),\n baseUrl: provider.baseUrl\n };\n if (\"docsUrl\" in provider) {\n view.docsUrl = provider.docsUrl;\n }\n if (\"summary\" in provider) {\n view.summary = provider.summary;\n }\n if (\"freshness\" in provider) {\n view.freshness = provider.freshness as BochaFreshnessValue;\n }\n if (\"searchDepth\" in provider) {\n view.searchDepth = provider.searchDepth as TavilySearchDepthValue;\n }\n if (\"includeAnswer\" in provider) {\n view.includeAnswer = Boolean(provider.includeAnswer);\n }\n return view;\n}\n\nexport function buildSearchView(config: Config): ConfigView[\"search\"] {\n return {\n provider: config.search.provider,\n enabledProviders: [...config.search.enabledProviders],\n defaults: {\n maxResults: config.search.defaults.maxResults\n },\n providers: {\n bocha: toSearchProviderView(config, \"bocha\", config.search.providers.bocha),\n tavily: toSearchProviderView(config, \"tavily\", config.search.providers.tavily),\n brave: toSearchProviderView(config, \"brave\", config.search.providers.brave)\n }\n };\n}\n\nfunction replaceSearchConfig(\n config: Config,\n search: SearchConfig,\n refs: Config[\"secrets\"][\"refs\"] = config.secrets.refs\n): Config {\n return {\n ...config,\n search,\n secrets: refs === config.secrets.refs ? config.secrets : { ...config.secrets, refs }\n };\n}\n\nfunction applyActiveSearchProviderPatch(config: Config, provider: SearchConfigUpdate[\"provider\"]): Config {\n if (!isSearchProviderName(provider)) {\n return config;\n }\n return replaceSearchConfig(config, { ...config.search, provider });\n}\n\nfunction applyEnabledSearchProvidersPatch(config: Config, enabledProviders: SearchConfigUpdate[\"enabledProviders\"]): Config {\n if (!Array.isArray(enabledProviders)) {\n return config;\n }\n const nextEnabledProviders = Array.from(new Set(\n enabledProviders.filter((value): value is SearchProviderName => isSearchProviderName(value))\n ));\n return replaceSearchConfig(config, { ...config.search, enabledProviders: nextEnabledProviders });\n}\n\nfunction applySearchDefaultsPatch(config: Config, defaults: SearchConfigUpdate[\"defaults\"]): Config {\n if (!defaults || !Object.prototype.hasOwnProperty.call(defaults, \"maxResults\")) {\n return config;\n }\n const nextMaxResults = defaults.maxResults;\n if (typeof nextMaxResults === \"number\" && Number.isFinite(nextMaxResults)) {\n return replaceSearchConfig(config, {\n ...config.search,\n defaults: {\n ...config.search.defaults,\n maxResults: Math.max(1, Math.min(50, Math.trunc(nextMaxResults)))\n }\n });\n }\n return config;\n}\n\nfunction applyBochaSearchPatch(config: Config, patch: BochaSearchPatch | undefined): Config {\n if (!patch) {\n return config;\n }\n let nextRefs = config.secrets.refs;\n let nextProvider = config.search.providers.bocha;\n if (Object.prototype.hasOwnProperty.call(patch, \"apiKey\")) {\n nextProvider = { ...nextProvider, apiKey: patch.apiKey ?? \"\" };\n nextRefs = clearSecretRef(nextRefs, \"search.providers.bocha.apiKey\");\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"baseUrl\")) {\n nextProvider = {\n ...nextProvider,\n baseUrl: normalizeOptionalString(patch.baseUrl) ?? \"https://api.bocha.cn/v1/web-search\"\n };\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"docsUrl\")) {\n nextProvider = {\n ...nextProvider,\n docsUrl: normalizeOptionalString(patch.docsUrl) ?? BOCHA_OPEN_URL\n };\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"summary\")) {\n nextProvider = { ...nextProvider, summary: Boolean(patch.summary) };\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"freshness\")) {\n const freshness = normalizeOptionalString(patch.freshness);\n nextProvider = {\n ...nextProvider,\n freshness:\n freshness === \"noLimit\" ||\n freshness === \"oneDay\" ||\n freshness === \"oneWeek\" ||\n freshness === \"oneMonth\" ||\n freshness === \"oneYear\"\n ? freshness\n : \"noLimit\"\n };\n }\n return replaceSearchConfig(\n config,\n {\n ...config.search,\n providers: { ...config.search.providers, bocha: nextProvider }\n },\n nextRefs\n );\n}\n\nfunction applyTavilySearchPatch(config: Config, patch: TavilySearchPatch | undefined): Config {\n if (!patch) {\n return config;\n }\n let nextRefs = config.secrets.refs;\n let nextProvider = config.search.providers.tavily;\n if (Object.prototype.hasOwnProperty.call(patch, \"apiKey\")) {\n nextProvider = { ...nextProvider, apiKey: patch.apiKey ?? \"\" };\n nextRefs = clearSecretRef(nextRefs, \"search.providers.tavily.apiKey\");\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"baseUrl\")) {\n nextProvider = {\n ...nextProvider,\n baseUrl: normalizeOptionalString(patch.baseUrl) ?? \"https://api.tavily.com/search\"\n };\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"searchDepth\")) {\n const searchDepth = normalizeOptionalString(patch.searchDepth);\n nextProvider = {\n ...nextProvider,\n searchDepth: searchDepth === \"advanced\" ? \"advanced\" : \"basic\"\n };\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"includeAnswer\")) {\n nextProvider = { ...nextProvider, includeAnswer: Boolean(patch.includeAnswer) };\n }\n return replaceSearchConfig(\n config,\n {\n ...config.search,\n providers: { ...config.search.providers, tavily: nextProvider }\n },\n nextRefs\n );\n}\n\nfunction applyBraveSearchPatch(config: Config, patch: BraveSearchPatch | undefined): Config {\n if (!patch) {\n return config;\n }\n let nextRefs = config.secrets.refs;\n let nextProvider = config.search.providers.brave;\n if (Object.prototype.hasOwnProperty.call(patch, \"apiKey\")) {\n nextProvider = { ...nextProvider, apiKey: patch.apiKey ?? \"\" };\n nextRefs = clearSecretRef(nextRefs, \"search.providers.brave.apiKey\");\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"baseUrl\")) {\n nextProvider = {\n ...nextProvider,\n baseUrl: normalizeOptionalString(patch.baseUrl) ?? \"https://api.search.brave.com/res/v1/web/search\"\n };\n }\n return replaceSearchConfig(\n config,\n {\n ...config.search,\n providers: { ...config.search.providers, brave: nextProvider }\n },\n nextRefs\n );\n}\n\nexport function updateSearch(configPath: string, patch: SearchConfigUpdate): ConfigView[\"search\"] {\n const config = loadConfig(configPath);\n const nextConfig = applyBraveSearchPatch(\n applyTavilySearchPatch(\n applyBochaSearchPatch(\n applySearchDefaultsPatch(\n applyEnabledSearchProvidersPatch(\n applyActiveSearchProviderPatch(config, patch.provider),\n patch.enabledProviders\n ),\n patch.defaults\n ),\n patch.providers?.bocha\n ),\n patch.providers?.tavily\n ),\n patch.providers?.brave\n );\n const next = ConfigSchema.parse(nextConfig);\n saveConfig(next, configPath);\n return buildSearchView(next);\n}\n","import {\n loadConfig,\n saveConfig,\n ConfigSchema,\n DEFAULT_WORKSPACE_PATH,\n probeFeishu,\n type Config,\n type ConfigActionExecuteRequest,\n type ConfigActionExecuteResult,\n type ConfigActionManifest,\n type ConfigUiHint,\n type ConfigUiHints,\n type ProviderConfig,\n buildConfigSchema,\n getProviderName,\n getPackageVersion,\n hasSecretRef,\n isSensitiveConfigPath,\n type ProviderSpec,\n normalizeProviderModelConfig\n} from \"@nextclaw/core\";\nimport type { LlmProviderManager } from \"@nextclaw/kernel\";\nimport {\n buildExtensionChannelUiHints,\n buildProjectedChannelMeta,\n getProjectedChannelConfig,\n getProjectedChannelMap,\n mergeProjectedExtensionChannelConfig,\n normalizeExtensionProjectionOptions,\n type ExtensionConfigProjectionOptions\n} from \"@nextclaw-server/features/config/utils/extension-channel-config-projection.utils.js\";\nimport { createDefaultProviderConfigFromSpec } from \"@nextclaw-server/features/config/utils/default-provider-config.utils.js\";\nimport { findServerBuiltinProviderByName, listServerBuiltinProviders } from \"@nextclaw-server/features/config/providers/server-builtin-provider.provider.js\";\nimport { normalizeRuntimeEntryConfig } from \"@nextclaw-server/features/config/utils/runtime-entry-config.utils.js\";\nimport { buildSearchView, SEARCH_PROVIDER_META } from \"@nextclaw-server/features/config/utils/search-config.utils.js\";\nimport type {\n ConfigMetaView,\n RuntimeConfigUpdate,\n ConfigSchemaResponse,\n ConfigView,\n ProviderCreateRequest,\n ProviderConfigUpdate,\n ProviderConnectionTestRequest,\n ProviderConnectionTestResult,\n ProviderConfigView,\n ProviderInstanceView,\n ProvidersView,\n ProviderTemplatesView,\n SecretsConfigUpdate,\n SecretsView\n} from \"@nextclaw-server/shared/types/server-api.types.js\";\nexport { updateSearch } from \"@nextclaw-server/features/config/utils/search-config.utils.js\";\n\nconst MASK_MIN_LENGTH = 8;\nconst EXTRA_SENSITIVE_PATH_PATTERNS = [/authorization/i, /cookie/i, /session/i, /bearer/i];\nconst PREFERRED_PROVIDER_ORDER = [\n \"nextclaw\",\n \"openai\", \"anthropic\", \"gemini\", \"openrouter\", \"dashscope-coding-plan\", \"dashscope\", \"deepseek\", \"minimax\",\n \"moonshot\", \"kimi-coding\",\n \"zhipu\"\n] as const;\n\nconst PREFERRED_PROVIDER_ORDER_INDEX: Map<string, number> = new Map(\n PREFERRED_PROVIDER_ORDER.map((name, index) => [name, index])\n);\nconst BUILTIN_PROVIDERS = listServerBuiltinProviders();\nconst BUILTIN_PROVIDER_NAMES = new Set(BUILTIN_PROVIDERS.map((spec) => spec.name));\nconst CUSTOM_PROVIDER_PREFIX = \"custom-\";\nconst PROVIDER_TEST_MAX_TOKENS = 16;\n\nfunction normalizeOptionalDisplayName(value: unknown): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction isCustomProviderName(name: string): boolean {\n return name.trim().length > 0 && !BUILTIN_PROVIDER_NAMES.has(name);\n}\n\nfunction resolveCustomProviderFallbackDisplayName(name: string): string {\n if (name.startsWith(CUSTOM_PROVIDER_PREFIX)) {\n const suffix = name.slice(CUSTOM_PROVIDER_PREFIX.length);\n if (/^\\d+$/.test(suffix)) {\n return `Custom ${suffix}`;\n }\n }\n return name;\n}\n\nfunction resolveProviderInstanceDisplayName(\n providerId: string,\n provider: ProviderConfig | undefined,\n spec?: ProviderSpec | null\n): string | undefined {\n const configDisplayName = normalizeOptionalDisplayName(provider?.displayName);\n return configDisplayName ?? spec?.displayName ?? (providerId.startsWith(CUSTOM_PROVIDER_PREFIX)\n ? resolveCustomProviderFallbackDisplayName(providerId)\n : providerId);\n}\n\nfunction findNextCustomProviderName(config: Config): string {\n const providers = config.providers as Record<string, ProviderConfig>;\n let index = 1;\n while (providers[`${CUSTOM_PROVIDER_PREFIX}${index}`]) {\n index += 1;\n }\n return `${CUSTOM_PROVIDER_PREFIX}${index}`;\n}\n\nfunction normalizeProviderId(value: unknown): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n if (!trimmed || trimmed.includes(\"/\")) {\n return null;\n }\n return trimmed;\n}\n\nfunction resolveProviderType(providerId: string, provider?: ProviderConfig | null): string | null {\n const configuredType = normalizeProviderId(provider?.providerType);\n if (configuredType && findServerBuiltinProviderByName(configuredType)) {\n return configuredType;\n }\n if (findServerBuiltinProviderByName(providerId)) {\n return providerId;\n }\n return null;\n}\n\nfunction findNextProviderId(config: Config, baseProviderId: string): string {\n const providers = config.providers as Record<string, ProviderConfig>;\n let providerId = baseProviderId;\n let index = 2;\n while (providers[providerId]) {\n providerId = `${baseProviderId}-${index}`;\n index += 1;\n }\n return providerId;\n}\n\nfunction resolveProviderDisplayNameSuffix(providerId: string, baseProviderId: string): string {\n if (providerId === baseProviderId) {\n return \"\";\n }\n const suffix = providerId.slice(baseProviderId.length + 1).trim();\n return suffix ? ` ${suffix}` : \"\";\n}\n\nfunction buildProviderScopedModels(providerId: string, models: string[]): string[] {\n return normalizeModelList(models).map((model) => {\n const slashIndex = model.indexOf(\"/\");\n const modelSuffix = slashIndex >= 0 ? model.slice(slashIndex + 1).trim() : model;\n return modelSuffix ? `${providerId}/${modelSuffix}` : \"\";\n }).filter(Boolean);\n}\n\nfunction clearSecretRefsByPrefix(refs: Config[\"secrets\"][\"refs\"], pathPrefix: string): Config[\"secrets\"][\"refs\"] {\n return Object.fromEntries(Object.entries(refs).filter(([key]) => key !== pathPrefix && !key.startsWith(`${pathPrefix}.`)));\n}\ntype ExecuteActionResult =\n | { ok: true; data: ConfigActionExecuteResult }\n | { ok: false; code: string; message: string; details?: Record<string, unknown> };\n\ntype ActionHandler = (\n params: {\n config: Config;\n action: ConfigActionManifest;\n }\n) => Promise<ConfigActionExecuteResult>;\n\nfunction matchesExtraSensitivePath(path: string): boolean {\n return path !== \"session\" &&\n !path.startsWith(\"session.\") &&\n !/^agents\\.runtimes\\.entries\\.[^.]+\\.config\\.resetSessionMetadataOnPromptTimeout$/.test(path) &&\n EXTRA_SENSITIVE_PATH_PATTERNS.some((pattern) => pattern.test(path));\n}\n\nfunction matchHint(path: string, hints: ConfigUiHints): ConfigUiHint | undefined {\n const direct = hints[path];\n if (direct) {\n return direct;\n }\n const segments = path.split(\".\");\n for (const [hintKey, hint] of Object.entries(hints)) {\n if (!hintKey.includes(\"*\")) {\n continue;\n }\n const hintSegments = hintKey.split(\".\");\n if (hintSegments.length !== segments.length) {\n continue;\n }\n let match = true;\n for (let index = 0; index < segments.length; index += 1) {\n if (hintSegments[index] !== \"*\" && hintSegments[index] !== segments[index]) {\n match = false;\n break;\n }\n }\n if (match) {\n return hint;\n }\n }\n return undefined;\n}\n\nfunction isSensitivePath(path: string, hints?: ConfigUiHints): boolean {\n if (hints) {\n const hint = matchHint(path, hints);\n if (hint?.sensitive !== undefined) {\n return Boolean(hint.sensitive);\n }\n }\n return isSensitiveConfigPath(path) || matchesExtraSensitivePath(path);\n}\n\nfunction sanitizePublicConfigValue<T>(value: T, prefix: string, hints?: ConfigUiHints): T {\n if (Array.isArray(value)) {\n const nextPath = prefix ? `${prefix}[]` : \"[]\";\n return value.map((entry) => sanitizePublicConfigValue(entry, nextPath, hints)) as T;\n }\n if (!value || typeof value !== \"object\") {\n return value;\n }\n const output: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value as Record<string, unknown>)) {\n const nextPath = prefix ? `${prefix}.${key}` : key;\n if (isSensitivePath(nextPath, hints)) {\n continue;\n }\n output[key] = sanitizePublicConfigValue(val, nextPath, hints);\n }\n return output as T;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction deepMerge(base: unknown, patch: unknown): unknown {\n if (!isObject(base) || !isObject(patch)) {\n return patch;\n }\n const result: Record<string, unknown> = { ...base };\n for (const [key, value] of Object.entries(patch)) {\n const previous = result[key];\n result[key] = deepMerge(previous, value);\n }\n return result;\n}\n\nfunction getPathValue(source: unknown, path: string): unknown {\n if (!source || typeof source !== \"object\") {\n return undefined;\n }\n const segments = path.split(\".\");\n let current: unknown = source;\n for (const segment of segments) {\n if (!current || typeof current !== \"object\") {\n return undefined;\n }\n current = (current as Record<string, unknown>)[segment];\n }\n return current;\n}\n\nfunction setPathValue(target: Record<string, unknown>, path: string, value: unknown): void {\n const segments = path.split(\".\");\n if (segments.length === 0) {\n return;\n }\n let current: Record<string, unknown> = target;\n for (let index = 0; index < segments.length - 1; index += 1) {\n const segment = segments[index];\n const next = current[segment];\n if (!isObject(next)) {\n current[segment] = {};\n }\n current = current[segment] as Record<string, unknown>;\n }\n current[segments[segments.length - 1]] = value;\n}\n\nfunction isMissingRequiredValue(value: unknown): boolean {\n if (value === undefined || value === null) {\n return true;\n }\n if (typeof value === \"string\") {\n return value.trim().length === 0;\n }\n if (Array.isArray(value)) {\n return value.length === 0;\n }\n return false;\n}\n\nfunction resolveRuntimeConfig(config: Config, draftConfig?: Record<string, unknown>): Config {\n if (!draftConfig || Object.keys(draftConfig).length === 0) {\n return config;\n }\n const merged = deepMerge(config, draftConfig);\n return ConfigSchema.parse(merged);\n}\n\nfunction getActionById(config: Config, actionId: string): ConfigActionManifest | null {\n const actions = buildConfigSchemaView(config).actions;\n return actions.find((item) => item.id === actionId) ?? null;\n}\n\nfunction messageOrDefault(\n action: ConfigActionManifest,\n kind: \"success\" | \"failure\",\n fallback: string\n): string {\n const text = kind === \"success\" ? action.success?.message : action.failure?.message;\n return text?.trim() ? text : fallback;\n}\n\nasync function runFeishuVerifyAction(params: {\n config: Config;\n action: ConfigActionManifest;\n}): Promise<ConfigActionExecuteResult> {\n const { config, action } = params;\n const appId = String(config.channels.feishu.appId ?? \"\").trim();\n const appSecret = String(config.channels.feishu.appSecret ?? \"\").trim();\n if (!appId || !appSecret) {\n return {\n ok: false,\n status: \"failed\",\n message: messageOrDefault(action, \"failure\", \"Verification failed: missing credentials\"),\n data: {\n error: \"missing credentials (appId, appSecret)\"\n },\n nextActions: []\n };\n }\n\n const result = await probeFeishu(appId, appSecret);\n if (!result.ok) {\n return {\n ok: false,\n status: \"failed\",\n message: `${messageOrDefault(action, \"failure\", \"Verification failed\")}: ${result.error}`,\n data: {\n error: result.error,\n appId: result.appId ?? appId\n },\n nextActions: []\n };\n }\n\n const responseData: Record<string, unknown> = {\n appId: result.appId,\n botName: result.botName ?? null,\n botOpenId: result.botOpenId ?? null\n };\n\n const patch: Record<string, unknown> = {};\n for (const [targetPath, sourcePath] of Object.entries(action.resultMap ?? {})) {\n const mappedValue = sourcePath.startsWith(\"response.data.\")\n ? responseData[sourcePath.slice(\"response.data.\".length)]\n : undefined;\n if (mappedValue !== undefined) {\n setPathValue(patch, targetPath, mappedValue);\n }\n }\n\n return {\n ok: true,\n status: \"success\",\n message: messageOrDefault(\n action,\n \"success\",\n \"Verified. Please finish Feishu event subscription and app publishing before using.\"\n ),\n data: responseData,\n patch: Object.keys(patch).length > 0 ? patch : undefined,\n nextActions: []\n };\n}\n\nconst ACTION_HANDLERS: Record<string, ActionHandler> = {\n \"channels.feishu.verifyConnection\": runFeishuVerifyAction\n};\n\nfunction buildUiHints(config: Config, options?: ExtensionConfigProjectionOptions): ConfigUiHints {\n return buildConfigSchemaView(config, options).uiHints;\n}\n\nfunction maskApiKey(value: string): { apiKeySet: boolean; apiKeyMasked?: string } {\n if (!value) {\n return { apiKeySet: false };\n }\n if (value.length < MASK_MIN_LENGTH) {\n return { apiKeySet: true, apiKeyMasked: \"****\" };\n }\n return {\n apiKeySet: true,\n apiKeyMasked: `${value.slice(0, 2)}****${value.slice(-4)}`\n };\n}\n\nfunction normalizeModelList(input: string[] | null | undefined): string[] {\n if (!input || input.length === 0) {\n return [];\n }\n const deduped = new Set<string>();\n for (const item of input) {\n if (typeof item !== \"string\") {\n continue;\n }\n const trimmed = item.trim();\n if (!trimmed) {\n continue;\n }\n deduped.add(trimmed);\n }\n return [...deduped];\n}\n\nfunction toProviderView(\n config: Config,\n provider: ProviderConfig,\n providerId: string,\n uiHints: ConfigUiHints,\n spec?: ProviderSpec\n): ProviderInstanceView {\n const providerType = resolveProviderType(providerId, provider);\n const apiKeyPath = `providers.${providerId}.apiKey`;\n const apiKeyRefSet = hasSecretRef(config, apiKeyPath);\n const masked = maskApiKey(provider.apiKey);\n const extraHeaders =\n provider.extraHeaders && Object.keys(provider.extraHeaders).length > 0\n ? (sanitizePublicConfigValue(\n provider.extraHeaders,\n `providers.${providerId}.extraHeaders`,\n uiHints\n ) as Record<string, string>)\n : null;\n const view: ProviderInstanceView = {\n providerId,\n providerType,\n isBuiltInType: providerType !== null,\n isCustom: providerType === null,\n enabled: provider.enabled !== false,\n displayName: resolveProviderInstanceDisplayName(providerId, provider, spec),\n apiKeySet: masked.apiKeySet || apiKeyRefSet,\n apiKeyMasked: masked.apiKeyMasked ?? (apiKeyRefSet ? \"****\" : undefined),\n apiBase: provider.apiBase ?? null,\n extraHeaders: extraHeaders && Object.keys(extraHeaders).length > 0 ? extraHeaders : null,\n models: normalizeModelList(provider.models ?? []),\n modelConfig: normalizeProviderModelConfig(provider.modelConfig ?? {})\n };\n const supportsWireApi = Boolean(spec?.supportsWireApi) || providerType === null;\n if (supportsWireApi) {\n view.wireApi = provider.wireApi ?? spec?.defaultWireApi ?? \"auto\";\n }\n return view;\n}\n\nexport function buildConfigView(config: Config, options?: ExtensionConfigProjectionOptions): ConfigView {\n const uiHints = buildUiHints(config, options);\n const projectedChannels = getProjectedChannelMap(config, options);\n const providers: Record<string, ProviderConfigView> = {};\n for (const [providerId, provider] of Object.entries(config.providers)) {\n const providerConfig = provider as ProviderConfig;\n const spec = findServerBuiltinProviderByName(resolveProviderType(providerId, providerConfig) ?? \"\");\n providers[providerId] = toProviderView(config, providerConfig, providerId, uiHints, spec);\n }\n return {\n companion: sanitizePublicConfigValue(config.companion, \"companion\", uiHints),\n agents: sanitizePublicConfigValue(config.agents, \"agents\", uiHints),\n providers,\n search: buildSearchView(config),\n channels: sanitizePublicConfigValue(projectedChannels, \"channels\", uiHints),\n bindings: sanitizePublicConfigValue(config.bindings, \"bindings\", uiHints),\n session: sanitizePublicConfigValue(config.session, \"session\", uiHints),\n tools: sanitizePublicConfigValue(config.tools, \"tools\", uiHints),\n gateway: sanitizePublicConfigValue(config.gateway, \"gateway\", uiHints),\n ui: sanitizePublicConfigValue(config.ui, \"ui\", uiHints),\n secrets: {\n enabled: config.secrets.enabled,\n defaults: { ...config.secrets.defaults },\n providers: { ...config.secrets.providers },\n refs: { ...config.secrets.refs }\n } satisfies SecretsView\n };\n}\n\nfunction normalizeRuntimeEntries(\n entries: Record<string, unknown> | null | undefined,\n): Config[\"agents\"][\"runtimes\"][\"entries\"] {\n if (!entries || typeof entries !== \"object\" || Array.isArray(entries)) {\n return {};\n }\n\n const normalized: Config[\"agents\"][\"runtimes\"][\"entries\"] = {};\n for (const [rawId, rawEntry] of Object.entries(entries)) {\n const id = rawId.trim();\n if (!id || !rawEntry || typeof rawEntry !== \"object\" || Array.isArray(rawEntry)) {\n continue;\n }\n const entry = rawEntry as Record<string, unknown>;\n const type = normalizeOptionalString(entry.type);\n if (!type) {\n continue;\n }\n const normalizedIcon = normalizeRuntimeEntryIcon(entry.icon);\n normalized[id] = {\n enabled: typeof entry.enabled === \"boolean\" ? entry.enabled : true,\n ...(normalizeOptionalString(entry.label) ? { label: normalizeOptionalString(entry.label) ?? undefined } : {}),\n ...(normalizedIcon ? { icon: normalizedIcon } : {}),\n type,\n config: normalizeRuntimeEntryConfig(\n type,\n entry.config && typeof entry.config === \"object\" && !Array.isArray(entry.config)\n ? (entry.config as Record<string, unknown>)\n : {},\n ),\n };\n }\n return normalized;\n}\n\nfunction normalizeRuntimeEntryIcon(\n value: unknown,\n): { kind: \"image\"; src: string; alt?: string } | null {\n if (typeof value === \"string\") {\n const src = value.trim();\n return src ? { kind: \"image\", src } : null;\n }\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return null;\n }\n const src = normalizeOptionalString((value as Record<string, unknown>).src);\n if (!src) {\n return null;\n }\n const alt = normalizeOptionalString((value as Record<string, unknown>).alt);\n return {\n kind: \"image\",\n src,\n ...(alt ? { alt } : {}),\n };\n}\n\nfunction clearSecretRef(refs: Config[\"secrets\"][\"refs\"], path: string): Config[\"secrets\"][\"refs\"] {\n const { [path]: _removed, ...nextRefs } = refs;\n void _removed;\n return nextRefs;\n}\n\nexport function buildConfigMeta(config: Config, options?: ExtensionConfigProjectionOptions): ConfigMetaView {\n const channels = buildProjectedChannelMeta(config, options);\n return { search: SEARCH_PROVIDER_META, channels };\n}\n\nexport function buildProviderTemplatesView(): ProviderTemplatesView {\n const providerTemplates = BUILTIN_PROVIDERS.map((spec) => {\n return {\n id: spec.name,\n providerType: spec.name,\n displayName: spec.displayName ?? spec.name,\n apiProtocol: spec.apiProtocol,\n modelPrefix: spec.modelPrefix,\n keywords: spec.keywords,\n envKey: spec.envKey,\n isGateway: spec.isGateway,\n isLocal: spec.isLocal,\n defaultApiBase: spec.defaultApiBase,\n logo: spec.logo,\n apiBaseHelp: spec.apiBaseHelp,\n auth: spec.auth\n ? {\n kind: spec.auth.kind,\n displayName: spec.auth.displayName,\n note: spec.auth.note,\n methods: spec.auth.methods?.map((method) => ({\n id: method.id,\n label: method.label,\n hint: method.hint\n })),\n defaultMethodId: spec.auth.defaultMethodId,\n supportsCliImport: Boolean(spec.auth.cliCredential)\n }\n : undefined,\n defaultModels: normalizeModelList(spec.defaultModels ?? []),\n modelConfig: normalizeProviderModelConfig(spec.modelConfig ?? {}),\n supportsWireApi: spec.supportsWireApi,\n wireApiOptions: spec.wireApiOptions,\n defaultWireApi: spec.defaultWireApi\n };\n }).sort((left, right) => {\n const leftRank = PREFERRED_PROVIDER_ORDER_INDEX.get(left.id);\n const rightRank = PREFERRED_PROVIDER_ORDER_INDEX.get(right.id);\n if (leftRank !== undefined && rightRank !== undefined) {\n return leftRank - rightRank;\n }\n if (leftRank !== undefined) {\n return -1;\n }\n if (rightRank !== undefined) {\n return 1;\n }\n return left.id.localeCompare(right.id);\n });\n\n return { providerTemplates };\n}\n\nexport function buildProvidersView(config: Config): ProvidersView {\n const uiHints = buildUiHints(config);\n const providers: Record<string, ProviderInstanceView> = {};\n for (const [providerId, provider] of Object.entries(config.providers)) {\n const providerConfig = provider as ProviderConfig;\n const spec = findServerBuiltinProviderByName(resolveProviderType(providerId, providerConfig) ?? \"\");\n providers[providerId] = toProviderView(config, providerConfig, providerId, uiHints, spec);\n }\n return { providers };\n}\n\nexport function buildConfigSchemaView(_config: Config, options?: ExtensionConfigProjectionOptions): ConfigSchemaResponse {\n const base = buildConfigSchema({ version: getPackageVersion() });\n const extensionUiHints = buildExtensionChannelUiHints(options);\n if (Object.keys(extensionUiHints).length === 0) {\n return base;\n }\n return { ...base, uiHints: { ...base.uiHints, ...extensionUiHints } };\n}\n\nexport async function executeConfigAction(\n configPath: string,\n actionId: string,\n request: ConfigActionExecuteRequest\n): Promise<ExecuteActionResult> {\n const baseConfig = loadConfigOrDefault(configPath);\n const action = getActionById(baseConfig, actionId);\n if (!action) {\n return {\n ok: false,\n code: \"ACTION_NOT_FOUND\",\n message: `unknown action: ${actionId}`\n };\n }\n\n if (request.scope && request.scope !== action.scope) {\n return {\n ok: false,\n code: \"ACTION_SCOPE_MISMATCH\",\n message: `scope mismatch: expected ${action.scope}, got ${request.scope}`,\n details: {\n expectedScope: action.scope,\n requestScope: request.scope\n }\n };\n }\n\n const runtimeConfig = resolveRuntimeConfig(baseConfig, request.draftConfig);\n\n for (const requiredPath of action.requires ?? []) {\n const requiredValue = getPathValue(runtimeConfig, requiredPath);\n if (isMissingRequiredValue(requiredValue)) {\n return {\n ok: false,\n code: \"ACTION_PRECONDITION_FAILED\",\n message: `required field missing: ${requiredPath}`,\n details: {\n path: requiredPath\n }\n };\n }\n }\n\n const handler = ACTION_HANDLERS[action.id];\n if (!handler) {\n return {\n ok: false,\n code: \"ACTION_EXECUTION_FAILED\",\n message: `action handler not found for type ${action.type}`\n };\n }\n\n const result = await handler({\n config: runtimeConfig,\n action\n });\n\n return {\n ok: true,\n data: result\n };\n}\n\nexport function loadConfigOrDefault(configPath: string): Config {\n return loadConfig(configPath);\n}\n\nfunction createProviderForUpdate(providerId: string): ProviderConfig | null {\n const spec = findServerBuiltinProviderByName(providerId);\n if (!spec) {\n return null;\n }\n return createDefaultProviderConfigFromSpec(spec);\n}\n\nexport function updateModel(configPath: string, patch: { model?: string; workspace?: string }): ConfigView {\n const config = loadConfigOrDefault(configPath);\n\n if (typeof patch.model === \"string\") config.agents.defaults.model = patch.model;\n if (typeof patch.workspace === \"string\") {\n config.agents.defaults.workspace = normalizeOptionalString(patch.workspace) ?? DEFAULT_WORKSPACE_PATH;\n }\n\n const next = ConfigSchema.parse(config);\n saveConfig(next, configPath);\n return buildConfigView(next);\n}\n\nexport function updateProvider(\n configPath: string,\n providerId: string,\n patch: ProviderConfigUpdate\n): ProviderConfigView | null {\n const config = loadConfigOrDefault(configPath);\n const providers = config.providers as Record<string, ProviderConfig>;\n const provider = providers[providerId] ?? createProviderForUpdate(providerId);\n if (!provider) {\n return null;\n }\n providers[providerId] = provider;\n const requestedProviderType = Object.prototype.hasOwnProperty.call(patch, \"providerType\")\n ? normalizeProviderId(patch.providerType)\n : resolveProviderType(providerId, provider);\n const spec = findServerBuiltinProviderByName(requestedProviderType ?? \"\");\n if (Object.prototype.hasOwnProperty.call(patch, \"providerType\")) {\n provider.providerType = spec?.name ?? null;\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"displayName\")) {\n provider.displayName = normalizeOptionalDisplayName(patch.displayName) ?? \"\";\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"enabled\")) {\n provider.enabled = patch.enabled !== false;\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"apiKey\")) {\n provider.apiKey = patch.apiKey ?? \"\";\n config.secrets.refs = clearSecretRef(config.secrets.refs, `providers.${providerId}.apiKey`);\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"apiBase\")) {\n provider.apiBase = patch.apiBase ?? null;\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"extraHeaders\")) {\n provider.extraHeaders = patch.extraHeaders ?? null;\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"wireApi\") && (spec?.supportsWireApi || !spec)) {\n provider.wireApi = patch.wireApi ?? spec?.defaultWireApi ?? \"auto\";\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"models\")) {\n provider.models = normalizeModelList(patch.models ?? []);\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"modelConfig\")) {\n provider.modelConfig = normalizeProviderModelConfig(patch.modelConfig ?? {});\n }\n const next = ConfigSchema.parse(config);\n saveConfig(next, configPath);\n const uiHints = buildUiHints(next);\n const updated = (next.providers as Record<string, ProviderConfig>)[providerId];\n return toProviderView(next, updated, providerId, uiHints, spec ?? undefined);\n}\n\nexport function createProvider(\n configPath: string,\n patch: ProviderCreateRequest = {}\n): { providerId: string; provider: ProviderConfigView } | null {\n const config = loadConfigOrDefault(configPath);\n const providers = config.providers as Record<string, ProviderConfig>;\n const requestedProviderType = normalizeProviderId(patch.providerType);\n const spec = requestedProviderType ? findServerBuiltinProviderByName(requestedProviderType) : undefined;\n const fallbackProviderId = spec ? spec.name : findNextCustomProviderName(config);\n const requestedProviderId = normalizeProviderId(patch.providerId);\n if (requestedProviderId && providers[requestedProviderId]) {\n return null;\n }\n const providerId = requestedProviderId\n ? requestedProviderId\n : findNextProviderId(config, fallbackProviderId);\n const generatedDisplayName = spec\n ? `${spec.displayName}${resolveProviderDisplayNameSuffix(providerId, spec.name)}`\n : resolveCustomProviderFallbackDisplayName(providerId);\n const defaultModels = spec ? buildProviderScopedModels(providerId, spec.defaultModels ?? []) : [];\n providers[providerId] = {\n enabled: patch.enabled !== false,\n providerType: spec?.name ?? null,\n displayName: normalizeOptionalDisplayName(patch.displayName) ?? generatedDisplayName,\n apiKey: normalizeOptionalString(patch.apiKey) ?? \"\",\n apiBase: normalizeOptionalString(patch.apiBase) ?? spec?.defaultApiBase ?? null,\n extraHeaders: normalizeHeaders(patch.extraHeaders ?? null),\n wireApi: patch.wireApi ?? spec?.defaultWireApi ?? \"auto\",\n models: Object.prototype.hasOwnProperty.call(patch, \"models\")\n ? normalizeModelList(patch.models ?? [])\n : defaultModels,\n modelConfig: normalizeProviderModelConfig(patch.modelConfig ?? spec?.modelConfig ?? {})\n };\n const next = ConfigSchema.parse(config);\n saveConfig(next, configPath);\n const uiHints = buildUiHints(next);\n const created = (next.providers as Record<string, ProviderConfig>)[providerId];\n return {\n providerId,\n provider: toProviderView(next, created, providerId, uiHints, spec)\n };\n}\n\nexport function deleteProvider(configPath: string, providerId: string): boolean | null {\n const config = loadConfigOrDefault(configPath);\n const providers = config.providers as Record<string, ProviderConfig>;\n if (!providers[providerId]) {\n return null;\n }\n delete providers[providerId];\n config.secrets.refs = clearSecretRefsByPrefix(config.secrets.refs, `providers.${providerId}`);\n const next = ConfigSchema.parse(config);\n saveConfig(next, configPath);\n return true;\n}\n\nfunction normalizeOptionalString(value: unknown): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction normalizeHeaders(input: Record<string, string> | null | undefined): Record<string, string> | null {\n if (!input) {\n return null;\n }\n const entries = Object.entries(input)\n .map(([key, value]) => [key.trim(), String(value ?? \"\").trim()] as const)\n .filter(([key, value]) => key.length > 0 && value.length > 0);\n if (entries.length === 0) {\n return null;\n }\n return Object.fromEntries(entries);\n}\n\nfunction buildScopedProviderModel(\n providerName: string,\n model: string,\n spec?: ProviderSpec\n): string {\n const trimmed = model.trim();\n if (!trimmed) {\n return \"\";\n }\n if (trimmed.includes(\"/\")) {\n return trimmed;\n }\n if (isCustomProviderName(providerName)) {\n return trimmed;\n }\n const prefix = (spec?.modelPrefix ?? providerName).trim();\n if (!prefix) {\n return trimmed;\n }\n return `${prefix}/${trimmed}`;\n}\n\nfunction stripProviderIdPrefix(providerId: string, model: string): string {\n const prefix = `${providerId}/`;\n if (!model.startsWith(prefix)) {\n return model;\n }\n const stripped = model.slice(prefix.length).trim();\n return stripped || model;\n}\n\nfunction resolveTestModel(\n config: Config,\n providerId: string,\n requestedModel: string | null,\n provider: ProviderConfig,\n spec?: ProviderSpec\n): string | null {\n if (requestedModel) {\n return spec ? requestedModel.replace(`${providerId}/`, `${spec.name}/`) : stripProviderIdPrefix(providerId, requestedModel);\n }\n\n const providerModels = normalizeModelList(provider.models ?? [])\n .map((modelId) => {\n const providerModel = stripProviderIdPrefix(providerId, modelId);\n return spec ? buildScopedProviderModel(spec.name, providerModel, spec) : providerModel;\n })\n .filter((modelId) => modelId.length > 0);\n if (providerModels.length > 0) {\n return providerModels[0];\n }\n\n const defaultModel = normalizeOptionalString(config.agents.defaults.model);\n if (defaultModel) {\n const routedProvider = getProviderName(config, defaultModel);\n if (!routedProvider || routedProvider === providerId) {\n return spec ? defaultModel.replace(`${providerId}/`, `${spec.name}/`) : stripProviderIdPrefix(providerId, defaultModel);\n }\n }\n\n if (!spec) {\n return null;\n }\n const specDefaultModel = normalizeModelList(spec?.defaultModels ?? [])[0] ?? null;\n return specDefaultModel ?? defaultModel ?? null;\n}\n\nfunction stringifyError(error: unknown): string {\n const raw = error instanceof Error ? error.message : String(error);\n return raw.replace(/\\s+/g, \" \").trim();\n}\n\nexport async function testProviderConnection(\n configPath: string,\n providerId: string,\n patch: ProviderConnectionTestRequest,\n providerManager?: LlmProviderManager\n): Promise<ProviderConnectionTestResult | null> {\n const config = loadConfigOrDefault(configPath);\n const provider = (config.providers as Record<string, ProviderConfig>)[providerId];\n if (!provider) {\n return null;\n }\n\n const providerType = resolveProviderType(providerId, provider);\n const spec = findServerBuiltinProviderByName(providerType ?? \"\");\n const hasApiKeyPatch = Object.prototype.hasOwnProperty.call(patch, \"apiKey\");\n const providedApiKey = normalizeOptionalString(patch.apiKey);\n const currentApiKey = normalizeOptionalString(provider.apiKey);\n const apiKey = hasApiKeyPatch ? providedApiKey : currentApiKey;\n\n const hasApiBasePatch = Object.prototype.hasOwnProperty.call(patch, \"apiBase\");\n const patchedApiBase = normalizeOptionalString(patch.apiBase);\n const currentApiBase = normalizeOptionalString(provider.apiBase);\n const apiBase = hasApiBasePatch\n ? patchedApiBase ?? spec?.defaultApiBase ?? null\n : currentApiBase ?? spec?.defaultApiBase ?? null;\n\n const hasHeadersPatch = Object.prototype.hasOwnProperty.call(patch, \"extraHeaders\");\n const extraHeaders = hasHeadersPatch\n ? normalizeHeaders(patch.extraHeaders ?? null)\n : normalizeHeaders(provider.extraHeaders ?? null);\n\n const wireApi = (spec?.supportsWireApi || !spec)\n ? patch.wireApi ?? provider.wireApi ?? spec?.defaultWireApi ?? \"auto\"\n : null;\n\n if (!apiKey && !spec?.isLocal) {\n return {\n success: false,\n provider: providerId,\n latencyMs: 0,\n message: \"API key is required before testing the connection.\"\n };\n }\n\n const requestedModel = normalizeOptionalString(patch.model);\n const model = resolveTestModel(config, providerId, requestedModel, provider, spec ?? undefined);\n if (!model) {\n return {\n success: false,\n provider: providerId,\n latencyMs: 0,\n message: \"No test model found. Configure provider models or set a default model for this provider, then try again.\"\n };\n }\n\n const startedAtMs = Date.now();\n if (!providerManager) {\n return {\n success: false,\n provider: providerId,\n model,\n latencyMs: Date.now() - startedAtMs,\n message: \"Provider manager is unavailable.\"\n };\n }\n try {\n await providerManager.testConnection({\n providerName: providerType,\n apiKey,\n apiBase,\n defaultModel: model,\n extraHeaders,\n wireApi,\n messages: [{ role: \"user\", content: \"ping\" }],\n maxTokens: PROVIDER_TEST_MAX_TOKENS\n });\n return {\n success: true,\n provider: providerId,\n model,\n latencyMs: Date.now() - startedAtMs,\n message: \"Connection test passed.\"\n };\n } catch (error) {\n return {\n success: false,\n provider: providerId,\n model,\n latencyMs: Date.now() - startedAtMs,\n message: stringifyError(error) || \"Connection test failed.\"\n };\n }\n}\n\nexport function updateChannel(\n configPath: string,\n channelName: string,\n patch: Record<string, unknown>,\n options?: ExtensionConfigProjectionOptions\n): Record<string, unknown> | null {\n const config = loadConfigOrDefault(configPath);\n const normalizedOptions = normalizeExtensionProjectionOptions(options);\n const channel = getProjectedChannelConfig(config, channelName, normalizedOptions);\n if (!channel) {\n return null;\n }\n for (const key of Object.keys(patch)) {\n const path = `channels.${channelName}.${key}`;\n if (isSensitivePath(path)) {\n config.secrets.refs = clearSecretRef(config.secrets.refs, path);\n }\n }\n const mergedChannel = { ...channel, ...patch };\n const mergedExtensionConfig = mergeProjectedExtensionChannelConfig(config, channelName, mergedChannel, normalizedOptions);\n if (mergedExtensionConfig) {\n const next = ConfigSchema.parse(mergedExtensionConfig);\n saveConfig(next, configPath);\n return sanitizePublicConfigValue(\n getProjectedChannelConfig(next, channelName, normalizedOptions) ?? {},\n `channels.${channelName}`,\n buildUiHints(next, normalizedOptions)\n );\n }\n\n (config.channels as Record<string, Record<string, unknown>>)[channelName] = mergedChannel;\n const next = ConfigSchema.parse(config);\n saveConfig(next, configPath);\n return sanitizePublicConfigValue(\n getProjectedChannelConfig(next, channelName, normalizedOptions) ?? {},\n `channels.${channelName}`,\n buildUiHints(next, normalizedOptions)\n );\n}\n\ntype RuntimeAgentDefaultsPatch = NonNullable<NonNullable<RuntimeConfigUpdate[\"agents\"]>[\"defaults\"]>;\n\nfunction applyRuntimeAgentDefaultsPatch(defaults: Config[\"agents\"][\"defaults\"], defaultsPatch: RuntimeAgentDefaultsPatch | undefined): Config[\"agents\"][\"defaults\"] {\n if (!defaultsPatch) return defaults;\n let next = defaults;\n if (Object.prototype.hasOwnProperty.call(defaultsPatch, \"contextTokens\")) {\n const nextContextTokens = defaultsPatch.contextTokens;\n if (typeof nextContextTokens === \"number\" && Number.isFinite(nextContextTokens)) next = { ...next, contextTokens: Math.max(1000, Math.trunc(nextContextTokens)) };\n }\n if (Object.prototype.hasOwnProperty.call(defaultsPatch, \"engine\")) next = { ...next, engine: normalizeOptionalString(defaultsPatch.engine) ?? \"native\" };\n if (Object.prototype.hasOwnProperty.call(defaultsPatch, \"engineConfig\")) {\n const nextEngineConfig = defaultsPatch.engineConfig;\n if (nextEngineConfig && typeof nextEngineConfig === \"object\" && !Array.isArray(nextEngineConfig)) next = { ...next, engineConfig: { ...nextEngineConfig } };\n }\n return next;\n}\n\nexport function updateRuntime(configPath: string, patch: RuntimeConfigUpdate): Pick<ConfigView, \"companion\" | \"agents\" | \"bindings\" | \"session\"> {\n const config = loadConfigOrDefault(configPath);\n if (patch.companion && Object.prototype.hasOwnProperty.call(patch.companion, \"enabled\")) config.companion.enabled = Boolean(patch.companion.enabled);\n config.agents.defaults = applyRuntimeAgentDefaultsPatch(config.agents.defaults, patch.agents?.defaults);\n if (patch.agents && Object.prototype.hasOwnProperty.call(patch.agents, \"list\")) {\n config.agents.list = (patch.agents.list ?? []).map((entry) => {\n const normalizedEngine = normalizeOptionalString(entry.engine);\n const hasEngineConfig =\n entry.engineConfig &&\n typeof entry.engineConfig === \"object\" &&\n !Array.isArray(entry.engineConfig);\n return {\n ...entry,\n default: Boolean(entry.default),\n ...(normalizedEngine ? { engine: normalizedEngine } : {}),\n ...(hasEngineConfig ? { engineConfig: { ...entry.engineConfig } } : {})\n };\n });\n }\n\n if (patch.agents?.runtimes && Object.prototype.hasOwnProperty.call(patch.agents.runtimes, \"entries\")) {\n config.agents.runtimes.entries = normalizeRuntimeEntries(\n patch.agents.runtimes.entries as Record<string, unknown> | null | undefined,\n );\n }\n\n if (Object.prototype.hasOwnProperty.call(patch, \"bindings\")) {\n config.bindings = patch.bindings ?? [];\n }\n\n if (patch.session) {\n config.session = {\n ...config.session,\n ...patch.session\n };\n }\n\n const next = ConfigSchema.parse(config);\n saveConfig(next, configPath);\n const view = buildConfigView(next);\n return {\n companion: view.companion,\n agents: view.agents,\n bindings: view.bindings ?? [],\n session: view.session ?? {}\n };\n}\n\nexport function updateSecrets(\n configPath: string,\n patch: SecretsConfigUpdate\n): SecretsView {\n const config = loadConfigOrDefault(configPath);\n\n if (Object.prototype.hasOwnProperty.call(patch, \"enabled\")) {\n config.secrets.enabled = Boolean(patch.enabled);\n }\n\n if (patch.defaults) {\n const nextDefaults = { ...config.secrets.defaults };\n for (const source of [\"env\", \"file\", \"exec\"] as const) {\n if (!Object.prototype.hasOwnProperty.call(patch.defaults, source)) {\n continue;\n }\n const value = patch.defaults[source];\n if (typeof value === \"string\" && value.trim()) {\n nextDefaults[source] = value.trim();\n } else {\n delete nextDefaults[source];\n }\n }\n config.secrets.defaults = nextDefaults;\n }\n\n if (Object.prototype.hasOwnProperty.call(patch, \"providers\")) {\n config.secrets.providers = (patch.providers ?? {}) as Config[\"secrets\"][\"providers\"];\n }\n\n if (Object.prototype.hasOwnProperty.call(patch, \"refs\")) {\n config.secrets.refs = (patch.refs ?? {}) as Config[\"secrets\"][\"refs\"];\n }\n\n const next = ConfigSchema.parse(config);\n saveConfig(next, configPath);\n return {\n enabled: next.secrets.enabled,\n defaults: { ...next.secrets.defaults },\n providers: { ...next.secrets.providers },\n refs: { ...next.secrets.refs }\n };\n}\n","import type { Context } from \"hono\";\nimport type {\n CronActionResult,\n CronCreateRequest,\n CronCreateResult,\n CronEnableRequest,\n CronJobView,\n CronRunRequest\n} from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport { err, ok, readJson, readNonEmptyString } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport type { CronJobEntry, UiCronHost, UiRouterOptions } from \"@nextclaw-server/app/types/router-options.types.js\";\n\nfunction toIsoTime(value?: number | null): string | null {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n return null;\n }\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) {\n return null;\n }\n return date.toISOString();\n}\n\nfunction buildCronJobView(job: CronJobEntry): CronJobView {\n return {\n id: job.id,\n name: job.name,\n enabled: job.enabled,\n schedule: job.schedule,\n payload: job.payload,\n state: {\n nextRunAt: toIsoTime(job.state.nextRunAtMs),\n lastRunAt: toIsoTime(job.state.lastRunAtMs),\n lastStatus: job.state.lastStatus ?? null,\n lastError: job.state.lastError ?? null\n },\n createdAt: new Date(job.createdAtMs).toISOString(),\n updatedAt: new Date(job.updatedAtMs).toISOString(),\n deleteAfterRun: job.deleteAfterRun\n };\n}\n\nfunction findCronJob(service: UiCronHost, id: string): CronJobEntry | null {\n const jobs = service.listJobs(true);\n return jobs.find((job) => job.id === id) ?? null;\n}\n\ntype CronCreateParams = Parameters<UiCronHost[\"addJob\"]>[0];\ntype CronCreateInput = CronCreateRequest & Record<string, unknown>;\nconst legacyCronDeliveryKeys = [\"deliver\", \"channel\", \"to\", \"accountId\", \"account_id\"] as const;\n\nfunction normalizeCronSchedule(schedule: CronCreateRequest[\"schedule\"] | undefined): CronJobEntry[\"schedule\"] | null {\n if (!schedule) {\n return null;\n }\n if (schedule.kind === \"every\") {\n if (typeof schedule.everyMs !== \"number\" || !Number.isFinite(schedule.everyMs) || schedule.everyMs <= 0) {\n return null;\n }\n return { kind: \"every\", everyMs: schedule.everyMs };\n }\n if (schedule.kind === \"at\") {\n if (typeof schedule.atMs !== \"number\" || !Number.isFinite(schedule.atMs)) {\n return null;\n }\n return { kind: \"at\", atMs: schedule.atMs };\n }\n if (schedule.kind === \"cron\") {\n const expr = readNonEmptyString(schedule.expr);\n if (!expr) {\n return null;\n }\n const tz = readNonEmptyString(schedule.tz);\n return tz ? { kind: \"cron\", expr, tz } : { kind: \"cron\", expr };\n }\n return null;\n}\n\nfunction readLegacyDeliveryKey(input: Record<string, unknown>): string | null {\n return legacyCronDeliveryKeys.find((key) => input[key] !== undefined) ?? null;\n}\n\nfunction readCronCreateParams(input: CronCreateInput): { params: CronCreateParams } | { error: string } {\n const legacyDeliveryKey = readLegacyDeliveryKey(input);\n if (legacyDeliveryKey) {\n return { error: `cron jobs do not accept ${legacyDeliveryKey}; put delivery instructions in message and use the message tool at run time` };\n }\n const name = readNonEmptyString(input.name);\n if (!name) {\n return { error: \"name must be a non-empty string\" };\n }\n const message = readNonEmptyString(input.message);\n if (!message) {\n return { error: \"message must be a non-empty string\" };\n }\n const schedule = normalizeCronSchedule(input.schedule);\n if (!schedule) {\n return { error: \"schedule must be a valid at/every/cron definition\" };\n }\n return {\n params: {\n name,\n message,\n schedule,\n agentId: readNonEmptyString(input.agentId),\n sessionId: readNonEmptyString(input.sessionId),\n deleteAfterRun: input.deleteAfterRun === true\n }\n };\n}\n\nexport class CronRoutesController {\n constructor(private readonly options: UiRouterOptions) {}\n\n readonly listJobs = (c: Context) => {\n if (!this.options.cron) {\n return c.json(err(\"NOT_AVAILABLE\", \"cron service unavailable\"), 503);\n }\n const query = c.req.query();\n const enabledOnly =\n query.enabledOnly === \"1\" ||\n query.enabledOnly === \"true\" ||\n query.enabledOnly === \"yes\" ||\n query.all === \"0\" ||\n query.all === \"false\" ||\n query.all === \"no\";\n const includeDisabled = !enabledOnly;\n const jobs = this.options.cron.listJobs(includeDisabled).map((job) => buildCronJobView(job as CronJobEntry));\n return c.json(ok({ jobs, total: jobs.length }));\n };\n\n readonly createJob = async (c: Context) => {\n if (!this.options.cron) {\n return c.json(err(\"NOT_AVAILABLE\", \"cron service unavailable\"), 503);\n }\n const body = await readJson<CronCreateInput>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n const normalized = readCronCreateParams(body.data);\n if (\"error\" in normalized) {\n return c.json(err(\"INVALID_BODY\", normalized.error), 400);\n }\n const job = this.options.cron.addJob(normalized.params);\n const data: CronCreateResult = { job: buildCronJobView(job as CronJobEntry) };\n return c.json(ok(data), 201);\n };\n\n readonly deleteJob = (c: Context) => {\n if (!this.options.cron) {\n return c.json(err(\"NOT_AVAILABLE\", \"cron service unavailable\"), 503);\n }\n const id = decodeURIComponent(c.req.param(\"id\"));\n const deleted = this.options.cron.removeJob(id);\n if (!deleted) {\n return c.json(err(\"NOT_FOUND\", `cron job not found: ${id}`), 404);\n }\n return c.json(ok({ deleted: true }));\n };\n\n readonly enableJob = async (c: Context) => {\n if (!this.options.cron) {\n return c.json(err(\"NOT_AVAILABLE\", \"cron service unavailable\"), 503);\n }\n const id = decodeURIComponent(c.req.param(\"id\"));\n const body = await readJson<CronEnableRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n if (typeof body.data.enabled !== \"boolean\") {\n return c.json(err(\"INVALID_BODY\", \"enabled must be boolean\"), 400);\n }\n const job = this.options.cron.enableJob(id, body.data.enabled);\n if (!job) {\n return c.json(err(\"NOT_FOUND\", `cron job not found: ${id}`), 404);\n }\n const data: CronActionResult = { job: buildCronJobView(job as CronJobEntry) };\n return c.json(ok(data));\n };\n\n readonly runJob = async (c: Context) => {\n if (!this.options.cron) {\n return c.json(err(\"NOT_AVAILABLE\", \"cron service unavailable\"), 503);\n }\n const id = decodeURIComponent(c.req.param(\"id\"));\n const body = await readJson<CronRunRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n const existing = findCronJob(this.options.cron, id);\n if (!existing) {\n return c.json(err(\"NOT_FOUND\", `cron job not found: ${id}`), 404);\n }\n const executed = await this.options.cron.runJob(id, Boolean(body.data.force));\n const after = findCronJob(this.options.cron, id);\n const data: CronActionResult = {\n job: after ? buildCronJobView(after) : null,\n executed\n };\n return c.json(ok(data));\n };\n}\n","import { readFile } from \"node:fs/promises\";\nimport type { Context } from \"hono\";\nimport type { UiNcpAssetPutView, UiNcpAssetView } from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport { err, ok } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport type { UiRouterOptions } from \"@nextclaw-server/app/types/router-options.types.js\";\n\nconst ASSET_CONTENT_BASE_PATH = \"/api/ncp/assets/content\";\n\nfunction buildAssetContentUrl(assetUri: string): string {\n const query = new URLSearchParams({ uri: assetUri });\n return `${ASSET_CONTENT_BASE_PATH}?${query.toString()}`;\n}\n\nfunction encodeContentDispositionFileName(fileName: string): string {\n return encodeURIComponent(fileName).replace(/\\*/g, \"%2A\");\n}\n\nfunction inferMimeTypeFromFileName(fileName: string): string | null {\n const normalized = fileName.trim().toLowerCase();\n if (normalized.endsWith(\".mp3\")) return \"audio/mpeg\";\n if (normalized.endsWith(\".m4a\")) return \"audio/mp4\";\n if (normalized.endsWith(\".wav\")) return \"audio/wav\";\n if (normalized.endsWith(\".ogg\")) return \"audio/ogg\";\n if (normalized.endsWith(\".opus\")) return \"audio/opus\";\n if (normalized.endsWith(\".flac\")) return \"audio/flac\";\n if (normalized.endsWith(\".aac\")) return \"audio/aac\";\n if (normalized.endsWith(\".weba\")) return \"audio/webm\";\n if (normalized.endsWith(\".mp4\") || normalized.endsWith(\".m4v\")) return \"video/mp4\";\n if (normalized.endsWith(\".mov\")) return \"video/quicktime\";\n if (normalized.endsWith(\".webm\")) return \"video/webm\";\n if (normalized.endsWith(\".mkv\")) return \"video/x-matroska\";\n if (normalized.endsWith(\".avi\")) return \"video/x-msvideo\";\n if (normalized.endsWith(\".wmv\")) return \"video/x-ms-wmv\";\n return null;\n}\n\nfunction resolveResponseMimeType(fileName: string, mimeType: string): string {\n const normalized = mimeType.trim().toLowerCase();\n if (normalized.length > 0 && normalized !== \"application/octet-stream\") {\n return normalized;\n }\n return inferMimeTypeFromFileName(fileName) ?? \"application/octet-stream\";\n}\n\nfunction toAssetView(record: {\n id: string;\n uri: string;\n fileName: string;\n mimeType: string;\n sizeBytes: number;\n}): UiNcpAssetView {\n return {\n id: record.id,\n name: record.fileName,\n mimeType: record.mimeType,\n sizeBytes: record.sizeBytes,\n assetUri: record.uri,\n url: buildAssetContentUrl(record.uri),\n };\n}\n\nexport class NcpAssetRoutesController {\n constructor(private readonly options: UiRouterOptions) {}\n\n private readonly getAssetApi = () => {\n const kernel = this.options.kernel;\n if (!kernel) {\n return undefined;\n }\n return {\n put: (input: {\n fileName: string;\n mimeType?: string | null;\n bytes: Uint8Array;\n createdAt?: Date;\n }) => kernel.assetStore.putBytes(input),\n stat: kernel.assetStore.statRecord,\n resolveContentPath: kernel.assetStore.resolveContentPath,\n };\n };\n\n readonly putAssets = async (c: Context) => {\n const assetApi = this.getAssetApi();\n if (!assetApi) {\n return c.json(err(\"NOT_AVAILABLE\", \"ncp asset api unavailable\"), 503);\n }\n\n let formData: FormData;\n try {\n formData = await c.req.raw.formData();\n } catch {\n return c.json(err(\"INVALID_BODY\", \"invalid multipart body\"), 400);\n }\n\n const files = Array.from(formData.values()).reduce<\n Array<{\n name: string;\n type: string;\n arrayBuffer: () => Promise<ArrayBuffer>;\n }>\n >((result, value) => {\n if (typeof value !== \"string\") {\n result.push(value as {\n name: string;\n type: string;\n arrayBuffer: () => Promise<ArrayBuffer>;\n });\n }\n return result;\n }, []);\n if (files.length === 0) {\n return c.json(err(\"INVALID_BODY\", \"no files provided\"), 400);\n }\n\n const assets: UiNcpAssetView[] = [];\n for (const file of files) {\n const record = await assetApi.put({\n fileName: file.name,\n mimeType: file.type || null,\n bytes: new Uint8Array(await file.arrayBuffer()),\n });\n assets.push(toAssetView(record));\n }\n\n const payload: UiNcpAssetPutView = { assets };\n return c.json(ok(payload));\n };\n\n readonly getAssetContent = async (c: Context): Promise<Response> => {\n const assetApi = this.getAssetApi();\n if (!assetApi) {\n return c.json(err(\"NOT_AVAILABLE\", \"ncp asset api unavailable\"), 503);\n }\n\n const uri = c.req.query(\"uri\")?.trim();\n if (!uri) {\n return c.json(err(\"INVALID_URI\", \"asset uri is required\"), 400);\n }\n\n const record = await assetApi.stat(uri);\n const contentPath = assetApi.resolveContentPath(uri);\n if (!record || !contentPath) {\n return c.json(err(\"NOT_FOUND\", `asset not found: ${uri}`), 404);\n }\n\n const body = await readFile(contentPath);\n return new Response(body, {\n headers: {\n \"content-type\": resolveResponseMimeType(\n record.fileName,\n record.mimeType || \"application/octet-stream\",\n ),\n \"content-disposition\": `inline; filename*=UTF-8''${encodeContentDispositionFileName(record.fileName)}`,\n },\n });\n };\n}\n","import { parseThinkingLevel } from \"@nextclaw/core\";\nimport type { SessionPatchUpdate } from \"@nextclaw-server/shared/types/server-api.types.js\";\n\nexport function applySessionPreferencePatch(params: {\n metadata: Record<string, unknown>;\n patch: SessionPatchUpdate;\n createInvalidThinkingError: (message: string) => Error;\n}): Record<string, unknown> {\n const nextMetadata = params.metadata;\n const { patch } = params;\n\n if (Object.prototype.hasOwnProperty.call(patch, \"label\")) {\n const label = typeof patch.label === \"string\" ? patch.label.trim() : \"\";\n if (label) {\n nextMetadata.label = label;\n } else {\n delete nextMetadata.label;\n }\n }\n\n if (Object.prototype.hasOwnProperty.call(patch, \"preferredModel\")) {\n const preferredModel = typeof patch.preferredModel === \"string\" ? patch.preferredModel.trim() : \"\";\n if (preferredModel) {\n nextMetadata.preferred_model = preferredModel;\n nextMetadata.model = preferredModel;\n } else {\n delete nextMetadata.preferred_model;\n delete nextMetadata.model;\n }\n }\n\n if (Object.prototype.hasOwnProperty.call(patch, \"preferredThinking\")) {\n const preferredThinking = typeof patch.preferredThinking === \"string\" ? patch.preferredThinking.trim() : \"\";\n if (!preferredThinking) {\n delete nextMetadata.preferred_thinking;\n } else {\n const normalizedThinking = parseThinkingLevel(preferredThinking);\n if (!normalizedThinking) {\n throw params.createInvalidThinkingError(\"preferredThinking must be a supported thinking level\");\n }\n nextMetadata.preferred_thinking = normalizedThinking;\n }\n }\n\n return nextMetadata;\n}\n","import { realpath, stat } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { expandHome } from \"@nextclaw/core\";\n\nexport class SessionProjectRootValidationError extends Error {\n constructor(\n readonly code:\n | \"PROJECT_ROOT_INVALID_TYPE\"\n | \"PROJECT_ROOT_NOT_FOUND\"\n | \"PROJECT_ROOT_NOT_DIRECTORY\",\n message: string,\n ) {\n super(message);\n this.name = \"SessionProjectRootValidationError\";\n }\n}\n\nfunction resolveCandidateProjectRoot(value: string): string {\n return resolve(expandHome(value));\n}\n\nexport async function normalizeSessionProjectRoot(\n value: unknown,\n): Promise<string | null> {\n if (value == null) {\n return null;\n }\n if (typeof value !== \"string\") {\n throw new SessionProjectRootValidationError(\n \"PROJECT_ROOT_INVALID_TYPE\",\n \"projectRoot must be a string or null\",\n );\n }\n\n const trimmed = value.trim();\n if (!trimmed) {\n return null;\n }\n\n const candidate = resolveCandidateProjectRoot(trimmed);\n let canonicalPath: string;\n try {\n canonicalPath = await realpath(candidate);\n } catch {\n throw new SessionProjectRootValidationError(\n \"PROJECT_ROOT_NOT_FOUND\",\n \"projectRoot directory does not exist\",\n );\n }\n\n const projectRootStats = await stat(canonicalPath);\n if (!projectRootStats.isDirectory()) {\n throw new SessionProjectRootValidationError(\n \"PROJECT_ROOT_NOT_DIRECTORY\",\n \"projectRoot must point to a directory\",\n );\n }\n\n return canonicalPath;\n}\n\nexport function isSessionProjectRootValidationError(\n error: unknown,\n): error is SessionProjectRootValidationError {\n return error instanceof SessionProjectRootValidationError;\n}\n","export const DEFAULT_MARKETPLACE_API_BASE = \"https://marketplace-api.nextclaw.io\";\n\nexport const CLAWBAY_CHANNEL_PLUGIN_NPM_SPEC = \"@clawbay/clawbay-channel\";\nexport const MARKETPLACE_REMOTE_PAGE_SIZE = 100;\nexport const MARKETPLACE_REMOTE_MAX_PAGES = 20;\n\nexport const MARKETPLACE_ZH_COPY_BY_SLUG: Record<string, { summary: string; description?: string }> = {\n weather: {\n summary: \"NextClaw 内置技能,用于天气查询工作流。\",\n description: \"在 NextClaw 中提供快速天气查询工作流。\"\n },\n summarize: {\n summary: \"NextClaw 内置技能,用于结构化摘要。\",\n description: \"在 NextClaw 中提供文件与长文本的摘要工作流。\"\n },\n github: {\n summary: \"NextClaw 内置技能,用于 GitHub 工作流。\",\n description: \"在 NextClaw 中提供 Issue、PR 与仓库相关工作流指引。\"\n },\n tmux: {\n summary: \"NextClaw 内置技能,用于终端/Tmux 协作工作流。\",\n description: \"在 NextClaw 中提供基于 Tmux 的任务执行工作流指引。\"\n },\n gog: {\n summary: \"NextClaw 内置技能,用于图谱导向生成工作流。\",\n description: \"在 NextClaw 中提供图谱与规划导向工作流指引。\"\n },\n pdf: {\n summary: \"Anthropic 技能,用于 PDF 读取/合并/拆分/OCR 工作流。\",\n description: \"使用该技能可读取、提取、合并、拆分、旋转并对 PDF 执行 OCR 处理。\"\n },\n docx: {\n summary: \"Anthropic 技能,用于创建和编辑 Word 文档。\",\n description: \"使用该技能可创建、读取、编辑并重构 .docx 文档。\"\n },\n pptx: {\n summary: \"Anthropic 技能,用于演示文稿操作。\",\n description: \"使用该技能可创建、解析、编辑并重组 .pptx 演示文稿。\"\n },\n xlsx: {\n summary: \"Anthropic 技能,用于表格文档工作流。\",\n description: \"使用该技能可打开、编辑、清洗并转换 .xlsx 与 .csv 等表格文件。\"\n },\n bird: {\n summary: \"社区技能,用于 X/Twitter 读取/搜索/发布工作流。\",\n description: \"使用 bird CLI 在代理工作流中读取线程、搜索帖子并起草推文/回复。\"\n },\n \"cloudflare-deploy\": {\n summary: \"OpenAI 精选技能,用于在 Cloudflare 上部署应用与基础设施。\",\n description: \"使用该技能可选择 Cloudflare 产品并部署 Workers、Pages 及相关服务。\"\n },\n \"channel-extension-clawbay\": {\n summary: \"Clawbay 官方渠道扩展,用于 NextClaw 集成。\",\n description: \"通过 extension channel 机制为 NextClaw 提供 Clawbay 渠道能力。\"\n }\n};\n","const MARKETPLACE_NETWORK_RETRY_ATTEMPTS = 5;\nconst MARKETPLACE_NETWORK_RETRY_BASE_MS = 350;\n\nfunction sleepMs(ms: number): Promise<void> {\n return new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n\nfunction isRetryableMarketplaceNetworkError(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n if (error.name === \"AbortError\") {\n return false;\n }\n\n const cause = (error as Error & { cause?: unknown }).cause;\n if (cause && typeof cause === \"object\" && cause !== null && \"code\" in cause) {\n const code = (cause as { code?: unknown }).code;\n if (\n code === \"ECONNRESET\"\n || code === \"ECONNREFUSED\"\n || code === \"ETIMEDOUT\"\n || code === \"EPIPE\"\n || code === \"ENOTFOUND\"\n || code === \"EAI_AGAIN\"\n ) {\n return true;\n }\n }\n\n if (error instanceof TypeError && error.message === \"fetch failed\") {\n return true;\n }\n return false;\n}\n\nexport async function runWithMarketplaceNetworkRetry<T>(action: () => Promise<T>): Promise<T> {\n let lastError: unknown;\n for (let attempt = 1; attempt <= MARKETPLACE_NETWORK_RETRY_ATTEMPTS; attempt += 1) {\n try {\n return await action();\n } catch (error) {\n lastError = error;\n if (attempt === MARKETPLACE_NETWORK_RETRY_ATTEMPTS || !isRetryableMarketplaceNetworkError(error)) {\n throw error;\n }\n await sleepMs(MARKETPLACE_NETWORK_RETRY_BASE_MS * 2 ** (attempt - 1));\n }\n }\n throw lastError;\n}\n","import type { MarketplaceItemView, MarketplaceListView } from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport { readErrorMessage } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport type { UiRouterOptions } from \"@nextclaw-server/app/types/router-options.types.js\";\nimport {\n DEFAULT_MARKETPLACE_API_BASE,\n MARKETPLACE_REMOTE_MAX_PAGES,\n MARKETPLACE_REMOTE_PAGE_SIZE,\n MARKETPLACE_ZH_COPY_BY_SLUG\n} from \"@nextclaw-server/features/marketplace/index.js\";\nimport { runWithMarketplaceNetworkRetry } from \"./marketplace-network-retry.utils.js\";\n\nconst MARKETPLACE_FETCH_TIMEOUT_MS = 12_000;\n\nexport function normalizeMarketplaceBaseUrl(options: UiRouterOptions): string {\n const configured = options.marketplace?.apiBaseUrl?.trim();\n if (!configured) {\n return DEFAULT_MARKETPLACE_API_BASE;\n }\n return configured.replace(/\\/$/, \"\");\n}\n\nexport function toMarketplaceUrl(baseUrl: string, path: string, query: Record<string, string | undefined> = {}): string {\n const url = new URL(path, `${baseUrl.replace(/\\/$/, \"\")}/`);\n for (const [key, value] of Object.entries(query)) {\n if (typeof value === \"string\" && value.length > 0) {\n url.searchParams.set(key, value);\n }\n }\n return url.toString();\n}\n\nexport async function fetchMarketplaceData<T>(params: {\n baseUrl: string;\n path: string;\n query?: Record<string, string | undefined>;\n}): Promise<{ ok: true; data: T } | { ok: false; status: number; message: string }> {\n const endpoint = toMarketplaceUrl(params.baseUrl, params.path, params.query);\n let response: Response;\n try {\n response = await runWithMarketplaceNetworkRetry(() =>\n fetch(endpoint, {\n method: \"GET\",\n headers: {\n Accept: \"application/json\"\n },\n signal: AbortSignal.timeout(MARKETPLACE_FETCH_TIMEOUT_MS)\n })\n );\n } catch (error) {\n return {\n ok: false,\n status: 503,\n message: error instanceof Error ? error.message : String(error)\n };\n }\n\n let payload: unknown = null;\n try {\n payload = await response.json();\n } catch {\n if (!response.ok) {\n return {\n ok: false,\n status: response.status,\n message: `marketplace request failed (${response.status})`\n };\n }\n return {\n ok: false,\n status: 502,\n message: \"invalid marketplace response\"\n };\n }\n\n if (!response.ok) {\n return {\n ok: false,\n status: response.status,\n message: readErrorMessage(payload, `marketplace request failed (${response.status})`)\n };\n }\n\n if (!payload || typeof payload !== \"object\" || !(\"ok\" in payload)) {\n return {\n ok: false,\n status: 502,\n message: \"invalid marketplace response\"\n };\n }\n\n const typed = payload as {\n ok?: boolean;\n data?: T;\n error?: {\n message?: string;\n };\n };\n\n if (!typed.ok) {\n return {\n ok: false,\n status: 502,\n message: readErrorMessage(payload, \"marketplace response returned error\")\n };\n }\n\n return {\n ok: true,\n data: typed.data as T\n };\n}\n\nfunction sanitizeMarketplaceItem<T extends Record<string, unknown>>(item: T): T {\n const next = { ...item } as T;\n delete (next as { sourceType?: unknown }).sourceType;\n return next;\n}\n\nfunction readLocalizedMap(value: unknown): Record<string, string> {\n const localized: Record<string, string> = {};\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return localized;\n }\n\n for (const [key, entry] of Object.entries(value as Record<string, unknown>)) {\n if (typeof entry !== \"string\" || entry.trim().length === 0) {\n continue;\n }\n localized[key] = entry.trim();\n }\n return localized;\n}\n\nfunction normalizeLocaleTag(value: string): string {\n return value.trim().toLowerCase().replace(/_/g, \"-\");\n}\n\nfunction pickLocaleFamilyValue(localized: Record<string, string>, localeFamily: string): string | undefined {\n const normalizedFamily = normalizeLocaleTag(localeFamily).split(\"-\")[0];\n if (!normalizedFamily) {\n return undefined;\n }\n\n let familyMatch: string | undefined;\n for (const [locale, text] of Object.entries(localized)) {\n const normalizedLocale = normalizeLocaleTag(locale);\n if (!normalizedLocale) {\n continue;\n }\n if (normalizedLocale === normalizedFamily) {\n return text;\n }\n if (!familyMatch && normalizedLocale.startsWith(`${normalizedFamily}-`)) {\n familyMatch = text;\n }\n }\n\n return familyMatch;\n}\n\nfunction normalizeLocalizedTextMap(primaryText: string, localized: unknown, zhFallback?: string): Record<string, string> {\n const next = readLocalizedMap(localized);\n if (!next.en) {\n next.en = pickLocaleFamilyValue(next, \"en\") ?? primaryText;\n }\n if (!next.zh) {\n next.zh = pickLocaleFamilyValue(next, \"zh\")\n ?? (zhFallback && zhFallback.trim().length > 0 ? zhFallback.trim() : next.en);\n }\n return next;\n}\n\nexport function normalizeMarketplaceItemForUi<T extends MarketplaceItemView | MarketplaceListView[\"items\"][number]>(item: T): T {\n const zhCopy = MARKETPLACE_ZH_COPY_BY_SLUG[item.slug];\n const next = {\n ...item,\n summaryI18n: normalizeLocalizedTextMap(item.summary, (item as { summaryI18n?: unknown }).summaryI18n, zhCopy?.summary)\n } as T & {\n summaryI18n: Record<string, string>;\n descriptionI18n?: Record<string, string>;\n };\n\n if (\"description\" in item && typeof item.description === \"string\" && item.description.trim().length > 0) {\n next.descriptionI18n = normalizeLocalizedTextMap(\n item.description,\n (item as { descriptionI18n?: unknown }).descriptionI18n,\n zhCopy?.description\n );\n }\n\n return next as T;\n}\n\nexport function toPositiveInt(raw: string | undefined, fallback: number): number {\n if (!raw) {\n return fallback;\n }\n const parsed = Number.parseInt(raw, 10);\n if (!Number.isFinite(parsed) || parsed <= 0) {\n return fallback;\n }\n return parsed;\n}\n\nexport async function fetchAllMarketplaceItems(params: {\n baseUrl: string;\n path: string;\n query?: Record<string, string | undefined>;\n}): Promise<\n | { ok: true; data: { sort: MarketplaceListView[\"sort\"]; query?: string; items: MarketplaceListView[\"items\"] } }\n | { ok: false; status: number; message: string }\n> {\n const items: MarketplaceListView[\"items\"] = [];\n let sort: MarketplaceListView[\"sort\"] = \"relevance\";\n let query: MarketplaceListView[\"query\"];\n\n for (let page = 1; page <= MARKETPLACE_REMOTE_MAX_PAGES; page += 1) {\n const result = await fetchMarketplaceData<MarketplaceListView>({\n baseUrl: params.baseUrl,\n path: params.path,\n query: {\n ...params.query,\n page: String(page),\n pageSize: String(MARKETPLACE_REMOTE_PAGE_SIZE)\n }\n });\n\n if (!result.ok) {\n return result;\n }\n\n const pageItems = Array.isArray(result.data.items) ? result.data.items : [];\n if (pageItems.length === 0) {\n break;\n }\n\n sort = result.data.sort;\n query = result.data.query;\n items.push(...pageItems);\n\n const pageSize =\n typeof result.data.pageSize === \"number\" && Number.isFinite(result.data.pageSize) && result.data.pageSize > 0\n ? result.data.pageSize\n : MARKETPLACE_REMOTE_PAGE_SIZE;\n if (pageItems.length < pageSize) {\n break;\n }\n }\n\n return {\n ok: true,\n data: {\n sort,\n ...(typeof query === \"string\" ? { query } : {}),\n items\n }\n };\n}\n\nexport async function fetchAllSkillMarketplaceItems(params: {\n baseUrl: string;\n query?: Record<string, string | undefined>;\n}): Promise<\n | { ok: true; data: { sort: MarketplaceListView[\"sort\"]; query?: string; items: MarketplaceListView[\"items\"] } }\n | { ok: false; status: number; message: string }\n> {\n return fetchAllMarketplaceItems({\n baseUrl: params.baseUrl,\n path: \"/api/v1/skills/items\",\n query: params.query\n });\n}\n\nexport async function fetchAllMcpMarketplaceItems(params: {\n baseUrl: string;\n query?: Record<string, string | undefined>;\n}): Promise<\n | { ok: true; data: { sort: MarketplaceListView[\"sort\"]; query?: string; items: MarketplaceListView[\"items\"] } }\n | { ok: false; status: number; message: string }\n> {\n return fetchAllMarketplaceItems({\n baseUrl: params.baseUrl,\n path: \"/api/v1/mcp/items\",\n query: params.query\n });\n}\n\nexport function sanitizeMarketplaceListItems(items: MarketplaceListView[\"items\"]): MarketplaceListView[\"items\"] {\n return items.map((item) => sanitizeMarketplaceItem(item));\n}\n\nexport function sanitizeMarketplaceItemView(item: MarketplaceItemView): MarketplaceItemView {\n return sanitizeMarketplaceItem(item);\n}\n","import { McpInstalledViewService } from \"@nextclaw/mcp\";\nimport type { Context } from \"hono\";\nimport type {\n MarketplaceInstalledView,\n MarketplaceItemView,\n MarketplaceMcpContentView,\n MarketplaceMcpDoctorResult,\n MarketplaceMcpInstallRequest,\n MarketplaceMcpInstallResult,\n MarketplaceMcpInstallSpec,\n MarketplaceMcpManageRequest,\n MarketplaceMcpManageResult,\n MarketplaceRecommendationView\n} from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport { loadConfigOrDefault } from \"@nextclaw-server/features/config/index.js\";\nimport { err, ok, readJson } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport type { UiRouterOptions } from \"@nextclaw-server/app/types/router-options.types.js\";\nimport { emitConfigUpdated } from \"@nextclaw-server/shared/utils/app-events.utils.js\";\nimport {\n fetchAllMcpMarketplaceItems,\n fetchMarketplaceData,\n normalizeMarketplaceItemForUi,\n sanitizeMarketplaceItemView,\n sanitizeMarketplaceListItems,\n toPositiveInt\n} from \"@nextclaw-server/features/marketplace/utils/marketplace-catalog.utils.js\";\n\nexport class McpMarketplaceController {\n constructor(\n private readonly options: UiRouterOptions,\n private readonly marketplaceBaseUrl: string\n ) {}\n\n readonly getInstalled = (c: Context) => {\n const service = new McpInstalledViewService({\n getConfig: () => loadConfigOrDefault(this.options.configPath)\n });\n const records = service.listInstalled().map((record) => ({\n type: \"mcp\" as const,\n id: record.name,\n spec: record.catalogSlug ?? record.name,\n label: record.displayName ?? record.name,\n enabled: record.enabled,\n runtimeStatus: record.enabled ? \"enabled\" : \"disabled\",\n transport: record.transport,\n scope: record.scope,\n catalogSlug: record.catalogSlug,\n vendor: record.vendor,\n docsUrl: record.docsUrl,\n homepage: record.homepage,\n trustLevel: record.trustLevel,\n source: record.source,\n installedAt: record.installedAt,\n toolCount: record.toolCount,\n accessible: record.accessible,\n lastReadyAt: record.lastReadyAt,\n lastDoctorAt: record.lastReadyAt,\n lastError: record.lastError\n }));\n\n return c.json(ok({\n type: \"mcp\",\n total: records.length,\n specs: records.map((record) => record.spec),\n records\n } satisfies MarketplaceInstalledView));\n };\n\n readonly listItems = async (c: Context) => {\n const query = c.req.query();\n const result = await fetchAllMcpMarketplaceItems({\n baseUrl: this.marketplaceBaseUrl,\n query: {\n q: query.q,\n tag: query.tag,\n sort: query.sort,\n page: query.page,\n pageSize: query.pageSize\n }\n });\n\n if (!result.ok) {\n return c.json(err(\"MARKETPLACE_UNAVAILABLE\", result.message), result.status as 500);\n }\n\n const items = sanitizeMarketplaceListItems(result.data.items).map((item) => normalizeMarketplaceItemForUi(item));\n const pageSize = Math.min(100, toPositiveInt(query.pageSize, 20));\n const requestedPage = toPositiveInt(query.page, 1);\n const totalPages = items.length === 0 ? 0 : Math.ceil(items.length / pageSize);\n const currentPage = totalPages === 0 ? 1 : Math.min(requestedPage, totalPages);\n\n return c.json(ok({\n total: items.length,\n page: currentPage,\n pageSize,\n totalPages,\n sort: result.data.sort,\n query: result.data.query,\n items: items.slice((currentPage - 1) * pageSize, currentPage * pageSize)\n }));\n };\n\n readonly getItem = async (c: Context) => {\n const slug = encodeURIComponent(c.req.param(\"slug\"));\n const result = await fetchMarketplaceData<MarketplaceItemView>({\n baseUrl: this.marketplaceBaseUrl,\n path: `/api/v1/mcp/items/${slug}`\n });\n if (!result.ok) {\n return c.json(err(\"MARKETPLACE_UNAVAILABLE\", result.message), result.status as 500);\n }\n return c.json(ok(normalizeMarketplaceItemForUi(sanitizeMarketplaceItemView(result.data))));\n };\n\n readonly getItemContent = async (c: Context) => {\n const slug = encodeURIComponent(c.req.param(\"slug\"));\n const result = await fetchMarketplaceData<MarketplaceMcpContentView>({\n baseUrl: this.marketplaceBaseUrl,\n path: `/api/v1/mcp/items/${slug}/content`\n });\n if (!result.ok) {\n return c.json(err(\"MARKETPLACE_UNAVAILABLE\", result.message), result.status as 500);\n }\n return c.json(ok(result.data));\n };\n\n readonly install = async (c: Context) => {\n const body = await readJson<MarketplaceMcpInstallRequest>(c.req.raw);\n if (!body.ok || !body.data || typeof body.data !== \"object\") {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n if (body.data.type && body.data.type !== \"mcp\") {\n return c.json(err(\"INVALID_BODY\", \"body.type does not match route type\"), 400);\n }\n\n const slug = typeof body.data.spec === \"string\" ? body.data.spec.trim() : \"\";\n if (!slug) {\n return c.json(err(\"INVALID_BODY\", \"non-empty spec is required\"), 400);\n }\n\n const installer = this.options.marketplace?.installer;\n if (!installer?.installMcp) {\n return c.json(err(\"NOT_AVAILABLE\", \"mcp installer is not configured\"), 503);\n }\n\n const itemResult = await fetchMarketplaceData<MarketplaceItemView>({\n baseUrl: this.marketplaceBaseUrl,\n path: `/api/v1/mcp/items/${encodeURIComponent(slug)}`\n });\n if (!itemResult.ok) {\n return c.json(err(\"MARKETPLACE_UNAVAILABLE\", itemResult.message), itemResult.status as 500);\n }\n\n const template = itemResult.data.install as MarketplaceMcpInstallSpec;\n if (template.kind !== \"template\") {\n return c.json(err(\"MARKETPLACE_CONTRACT_MISMATCH\", `unsupported mcp install kind: ${template.kind}`), 502);\n }\n\n try {\n const result = await installer.installMcp({\n ...body.data,\n template\n });\n emitConfigUpdated(this.options, \"mcp\");\n return c.json(ok({\n type: \"mcp\",\n spec: slug,\n name: result.name,\n message: result.message,\n output: result.output\n } satisfies MarketplaceMcpInstallResult));\n } catch (error) {\n return c.json(err(\"INSTALL_FAILED\", error instanceof Error ? error.message : String(error)), 400);\n }\n };\n\n readonly manage = async (c: Context) => {\n const body = await readJson<MarketplaceMcpManageRequest>(c.req.raw);\n if (!body.ok || !body.data || typeof body.data !== \"object\") {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n if (body.data.type && body.data.type !== \"mcp\") {\n return c.json(err(\"INVALID_BODY\", \"body.type does not match route type\"), 400);\n }\n\n const target = typeof body.data.id === \"string\" && body.data.id.trim().length > 0\n ? body.data.id.trim()\n : typeof body.data.spec === \"string\" && body.data.spec.trim().length > 0\n ? body.data.spec.trim()\n : \"\";\n if (!target) {\n return c.json(err(\"INVALID_BODY\", \"non-empty id/spec is required\"), 400);\n }\n\n const installer = this.options.marketplace?.installer;\n if (!installer) {\n return c.json(err(\"NOT_AVAILABLE\", \"marketplace installer is not configured\"), 503);\n }\n\n try {\n const action = body.data.action;\n const result = action === \"enable\"\n ? await installer.enableMcp?.(target)\n : action === \"disable\"\n ? await installer.disableMcp?.(target)\n : await installer.removeMcp?.(target);\n\n if (!result) {\n return c.json(err(\"NOT_AVAILABLE\", `mcp ${action} is not configured`), 503);\n }\n\n emitConfigUpdated(this.options, \"mcp\");\n return c.json(ok({\n type: \"mcp\",\n action,\n id: target,\n message: result.message,\n output: result.output\n } satisfies MarketplaceMcpManageResult));\n } catch (error) {\n return c.json(err(\"MANAGE_FAILED\", error instanceof Error ? error.message : String(error)), 400);\n }\n };\n\n readonly doctor = async (c: Context) => {\n const body = await readJson<{ name?: string; id?: string; spec?: string }>(c.req.raw);\n if (!body.ok || !body.data || typeof body.data !== \"object\") {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n const target = typeof body.data.name === \"string\" && body.data.name.trim().length > 0\n ? body.data.name.trim()\n : typeof body.data.id === \"string\" && body.data.id.trim().length > 0\n ? body.data.id.trim()\n : typeof body.data.spec === \"string\" && body.data.spec.trim().length > 0\n ? body.data.spec.trim()\n : \"\";\n if (!target) {\n return c.json(err(\"INVALID_BODY\", \"name/id/spec is required\"), 400);\n }\n\n const installer = this.options.marketplace?.installer;\n if (!installer?.doctorMcp) {\n return c.json(err(\"NOT_AVAILABLE\", \"mcp doctor is not configured\"), 503);\n }\n\n try {\n const result = await installer.doctorMcp(target);\n return c.json(ok(result satisfies MarketplaceMcpDoctorResult));\n } catch (error) {\n return c.json(err(\"DOCTOR_FAILED\", error instanceof Error ? error.message : String(error)), 400);\n }\n };\n\n readonly getRecommendations = async (c: Context) => {\n const query = c.req.query();\n const result = await fetchMarketplaceData<MarketplaceRecommendationView>({\n baseUrl: this.marketplaceBaseUrl,\n path: \"/api/v1/mcp/recommendations\",\n query: {\n scene: query.scene,\n limit: query.limit\n }\n });\n if (!result.ok) {\n return c.json(err(\"MARKETPLACE_UNAVAILABLE\", result.message), result.status as 500);\n }\n return c.json(ok({\n ...result.data,\n items: sanitizeMarketplaceListItems(result.data.items).map((item) => normalizeMarketplaceItemForUi(item))\n }));\n };\n}\n","import * as NextclawCore from \"@nextclaw/core\";\nimport { loadConfigOrDefault } from \"@nextclaw-server/features/config/index.js\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport type {\n MarketplaceInstalledRecord,\n MarketplaceInstalledView,\n MarketplaceItemView,\n MarketplaceListView\n} from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport { readNonEmptyString } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport type { SkillsLoaderConstructor, SkillsLoaderInstance, UiRouterOptions } from \"@nextclaw-server/app/types/router-options.types.js\";\nimport { MARKETPLACE_ZH_COPY_BY_SLUG } from \"@nextclaw-server/features/marketplace/index.js\";\n\nconst getWorkspacePathFromConfig = NextclawCore.getWorkspacePathFromConfig;\nconst MARKETPLACE_INSTALL_STATE_FILE = \".nextclaw-install.json\";\n\nfunction createSkillsLoader(workspace: string): SkillsLoaderInstance | null {\n const ctor = (NextclawCore as { SkillsLoader?: SkillsLoaderConstructor }).SkillsLoader;\n if (!ctor) {\n return null;\n }\n return new ctor(workspace);\n}\n\nexport function collectInstalledSkillRecords(options: UiRouterOptions): {\n records: MarketplaceInstalledRecord[];\n specs: string[];\n} {\n const config = loadConfigOrDefault(options.configPath);\n const workspacePath = getWorkspacePathFromConfig(config);\n const skillsLoader = createSkillsLoader(workspacePath);\n const availableSkillSet = new Set((skillsLoader?.listSkills(true) ?? []).map((skill) => skill.name));\n const listedSkills = skillsLoader?.listSkills(false) ?? [];\n\n const records = listedSkills\n .map((skill) => {\n const enabled = availableSkillSet.has(skill.name);\n const metadata = skillsLoader?.getSkillMetadata?.(skill);\n const description = readNonEmptyString(metadata?.description);\n const descriptionZh =\n readNonEmptyString(metadata?.description_zh) ??\n readNonEmptyString(metadata?.descriptionZh) ??\n readNonEmptyString(MARKETPLACE_ZH_COPY_BY_SLUG[skill.name]?.description);\n const marketplaceState = readMarketplaceSkillInstallState(dirname(skill.path));\n const origin = marketplaceState ? \"marketplace\" : undefined;\n const catalogSlug = marketplaceState?.slug;\n const installedAt = marketplaceState?.installedAt;\n return {\n type: \"skill\",\n id: skill.name,\n spec: skill.name,\n label: skill.name,\n description,\n descriptionZh,\n source: skill.source,\n origin,\n catalogSlug,\n installedAt,\n enabled,\n runtimeStatus: enabled ? \"enabled\" : \"disabled\"\n } satisfies MarketplaceInstalledRecord;\n })\n .sort((left, right) => left.spec.localeCompare(right.spec));\n\n return {\n specs: records.map((record) => record.spec),\n records\n };\n}\n\nfunction readMarketplaceSkillInstallState(destinationDir: string): {\n slug: string;\n installedAt?: string;\n} | null {\n const statePath = join(destinationDir, MARKETPLACE_INSTALL_STATE_FILE);\n if (!existsSync(statePath)) {\n return null;\n }\n\n try {\n const parsed = JSON.parse(readFileSync(statePath, \"utf8\")) as {\n schemaVersion?: unknown;\n type?: unknown;\n source?: unknown;\n slug?: unknown;\n installedAt?: unknown;\n };\n if (\n parsed.schemaVersion !== 1\n || parsed.type !== \"skill\"\n || parsed.source !== \"marketplace\"\n || typeof parsed.slug !== \"string\"\n ) {\n return null;\n }\n\n return {\n slug: parsed.slug,\n installedAt: typeof parsed.installedAt === \"string\" ? parsed.installedAt : undefined\n };\n } catch {\n return null;\n }\n}\n\nexport function collectSkillMarketplaceInstalledView(options: UiRouterOptions): MarketplaceInstalledView {\n const installed = collectInstalledSkillRecords(options);\n return {\n type: \"skill\",\n total: installed.records.length,\n specs: installed.specs,\n records: installed.records\n };\n}\n\nexport function collectKnownSkillNames(options: UiRouterOptions): Set<string> {\n const config = loadConfigOrDefault(options.configPath);\n const loader = createSkillsLoader(getWorkspacePathFromConfig(config));\n return new Set((loader?.listSkills(false) ?? []).map((skill) => skill.name));\n}\n\nexport function isSupportedMarketplaceSkillItem(\n item: MarketplaceItemView | MarketplaceListView[\"items\"][number],\n knownSkillNames: Set<string>\n): boolean {\n if (item.type !== \"skill\") {\n return false;\n }\n\n if (item.install.kind === \"marketplace\") {\n return true;\n }\n\n return item.install.kind === \"builtin\" && knownSkillNames.has(item.install.spec);\n}\n\nexport function findUnsupportedSkillInstallKind(\n items: Array<MarketplaceItemView | MarketplaceListView[\"items\"][number]>\n): string | null {\n for (const item of items) {\n if (item.type !== \"skill\") {\n continue;\n }\n const kind = item.install.kind as string;\n if (kind !== \"builtin\" && kind !== \"marketplace\") {\n return kind;\n }\n }\n return null;\n}\n","import type { Context } from \"hono\";\nimport type {\n MarketplaceItemView,\n MarketplaceListView,\n MarketplaceRecommendationView,\n MarketplaceScenesView,\n MarketplaceSkillContentView,\n MarketplaceSkillInstallRequest,\n MarketplaceSkillInstallResult,\n MarketplaceSkillManageRequest,\n MarketplaceSkillManageResult\n} from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport { err, ok, readJson } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport type { UiRouterOptions } from \"@nextclaw-server/app/types/router-options.types.js\";\nimport { emitConfigUpdated } from \"@nextclaw-server/shared/utils/app-events.utils.js\";\nimport {\n fetchMarketplaceData,\n normalizeMarketplaceItemForUi,\n sanitizeMarketplaceItemView,\n sanitizeMarketplaceListItems\n} from \"@nextclaw-server/features/marketplace/utils/marketplace-catalog.utils.js\";\nimport {\n collectKnownSkillNames,\n collectSkillMarketplaceInstalledView,\n findUnsupportedSkillInstallKind,\n isSupportedMarketplaceSkillItem\n} from \"@nextclaw-server/features/marketplace/utils/marketplace-installed.utils.js\";\n\ntype SupportedSkillMarketplaceListResult =\n | { ok: true; data: MarketplaceListView }\n | { ok: false; status: number; code: \"MARKETPLACE_UNAVAILABLE\" | \"MARKETPLACE_CONTRACT_MISMATCH\"; message: string };\n\nasync function installMarketplaceSkill(params: {\n options: UiRouterOptions;\n body: MarketplaceSkillInstallRequest;\n}): Promise<MarketplaceSkillInstallResult> {\n const { body, options } = params;\n const spec = typeof body.spec === \"string\" ? body.spec.trim() : \"\";\n if (!spec) {\n throw new Error(\"INVALID_BODY:non-empty spec is required\");\n }\n\n const installer = options.marketplace?.installer;\n if (!installer) {\n throw new Error(\"NOT_AVAILABLE:marketplace installer is not configured\");\n }\n if (!installer.installSkill) {\n throw new Error(\"NOT_AVAILABLE:skill installer is not configured\");\n }\n\n const result = await installer.installSkill({\n slug: spec,\n kind: body.kind,\n skill: body.skill,\n installPath: body.installPath,\n force: body.force\n });\n\n emitConfigUpdated(options, \"skills\");\n return {\n type: \"skill\",\n spec,\n message: result.message,\n output: result.output\n };\n}\n\nasync function manageMarketplaceSkill(params: {\n options: UiRouterOptions;\n body: MarketplaceSkillManageRequest;\n}): Promise<MarketplaceSkillManageResult> {\n const { body, options } = params;\n const action = body.action;\n const targetId = typeof body.id === \"string\" && body.id.trim().length > 0\n ? body.id.trim()\n : typeof body.spec === \"string\" && body.spec.trim().length > 0\n ? body.spec.trim()\n : \"\";\n\n if ((action !== \"update\" && action !== \"uninstall\") || !targetId) {\n throw new Error(\"INVALID_BODY:skill manage requires update/uninstall action and non-empty id/spec\");\n }\n\n const installer = options.marketplace?.installer;\n if (!installer) {\n throw new Error(\"NOT_AVAILABLE:marketplace installer is not configured\");\n }\n\n if (action === \"update\") {\n if (!installer.updateSkill) {\n throw new Error(\"NOT_AVAILABLE:skill update is not configured\");\n }\n\n const result = await installer.updateSkill({\n slug: targetId,\n force: body.force\n });\n emitConfigUpdated(options, \"skills\");\n\n return {\n type: \"skill\",\n action,\n id: targetId,\n message: result.message,\n output: result.output\n };\n }\n\n if (!installer.uninstallSkill) {\n throw new Error(\"NOT_AVAILABLE:skill uninstall is not configured\");\n }\n\n const result = await installer.uninstallSkill(targetId);\n emitConfigUpdated(options, \"skills\");\n\n return {\n type: \"skill\",\n action,\n id: targetId,\n message: result.message,\n output: result.output\n };\n}\n\nexport class SkillMarketplaceController {\n constructor(\n private readonly options: UiRouterOptions,\n private readonly marketplaceBaseUrl: string\n ) {}\n\n readonly getInstalled = (c: Context) => {\n return c.json(ok(collectSkillMarketplaceInstalledView(this.options)));\n };\n\n private readonly normalizeSupportedListData = (\n data: MarketplaceListView\n ): SupportedSkillMarketplaceListResult => {\n const normalizedItems = sanitizeMarketplaceListItems(data.items)\n .map((item) => normalizeMarketplaceItemForUi(item));\n const unsupportedKind = findUnsupportedSkillInstallKind(normalizedItems);\n if (unsupportedKind) {\n return {\n ok: false,\n code: \"MARKETPLACE_CONTRACT_MISMATCH\",\n status: 502,\n message: `unsupported skill install kind from marketplace api: ${unsupportedKind}`\n };\n }\n\n const knownSkillNames = collectKnownSkillNames(this.options);\n return {\n ok: true,\n data: {\n ...data,\n items: normalizedItems.filter((item) => isSupportedMarketplaceSkillItem(item, knownSkillNames))\n }\n };\n };\n\n private readonly loadSupportedListPage = async (\n query: Record<string, string | undefined>\n ): Promise<SupportedSkillMarketplaceListResult> => {\n const result = await fetchMarketplaceData<MarketplaceListView>({\n baseUrl: this.marketplaceBaseUrl,\n path: \"/api/v1/skills/items\",\n query\n });\n if (!result.ok) {\n return {\n ...result,\n code: \"MARKETPLACE_UNAVAILABLE\"\n };\n }\n return this.normalizeSupportedListData(result.data);\n };\n\n readonly listScenes = async (c: Context) => {\n const result = await fetchMarketplaceData<MarketplaceScenesView>({\n baseUrl: this.marketplaceBaseUrl,\n path: \"/api/v1/skills/scenes\"\n });\n if (!result.ok) {\n return c.json(err(\"MARKETPLACE_UNAVAILABLE\", result.message), result.status as 500);\n }\n\n return c.json(ok<MarketplaceScenesView>(result.data));\n };\n\n readonly listItems = async (c: Context) => {\n const query = c.req.query();\n const result = await this.loadSupportedListPage({\n q: query.q,\n scene: query.scene,\n tag: query.tag,\n sort: query.sort,\n page: query.page,\n pageSize: query.pageSize\n });\n\n if (!result.ok) {\n return c.json(err(result.code, result.message), result.status as 500);\n }\n\n return c.json(ok(result.data));\n };\n\n readonly getItem = async (c: Context) => {\n const slug = encodeURIComponent(c.req.param(\"slug\"));\n const result = await fetchMarketplaceData<MarketplaceItemView>({\n baseUrl: this.marketplaceBaseUrl,\n path: `/api/v1/skills/items/${slug}`\n });\n\n if (!result.ok) {\n return c.json(err(\"MARKETPLACE_UNAVAILABLE\", result.message), result.status as 500);\n }\n\n const knownSkillNames = collectKnownSkillNames(this.options);\n const sanitized = normalizeMarketplaceItemForUi(sanitizeMarketplaceItemView(result.data));\n const unsupportedKind = findUnsupportedSkillInstallKind([sanitized]);\n if (unsupportedKind) {\n return c.json(\n err(\"MARKETPLACE_CONTRACT_MISMATCH\", `unsupported skill install kind from marketplace api: ${unsupportedKind}`),\n 502\n );\n }\n if (!isSupportedMarketplaceSkillItem(sanitized, knownSkillNames)) {\n return c.json(err(\"NOT_FOUND\", \"marketplace item not supported by nextclaw\"), 404);\n }\n\n return c.json(ok(sanitized));\n };\n\n readonly getItemContent = async (c: Context) => {\n const slug = encodeURIComponent(c.req.param(\"slug\"));\n const result = await fetchMarketplaceData<MarketplaceItemView>({\n baseUrl: this.marketplaceBaseUrl,\n path: `/api/v1/skills/items/${slug}`\n });\n\n if (!result.ok) {\n return c.json(err(\"MARKETPLACE_UNAVAILABLE\", result.message), result.status as 500);\n }\n\n const knownSkillNames = collectKnownSkillNames(this.options);\n const sanitized = normalizeMarketplaceItemForUi(sanitizeMarketplaceItemView(result.data));\n const unsupportedKind = findUnsupportedSkillInstallKind([sanitized]);\n if (unsupportedKind) {\n return c.json(\n err(\"MARKETPLACE_CONTRACT_MISMATCH\", `unsupported skill install kind from marketplace api: ${unsupportedKind}`),\n 502\n );\n }\n if (!isSupportedMarketplaceSkillItem(sanitized, knownSkillNames)) {\n return c.json(err(\"NOT_FOUND\", \"marketplace item not supported by nextclaw\"), 404);\n }\n\n const contentResult = await fetchMarketplaceData<MarketplaceSkillContentView>({\n baseUrl: this.marketplaceBaseUrl,\n path: `/api/v1/skills/items/${slug}/content`\n });\n if (!contentResult.ok) {\n return c.json(err(\"MARKETPLACE_UNAVAILABLE\", contentResult.message), contentResult.status as 500);\n }\n\n return c.json(ok(contentResult.data));\n };\n\n readonly install = async (c: Context) => {\n const body = await readJson<MarketplaceSkillInstallRequest>(c.req.raw);\n if (!body.ok || !body.data || typeof body.data !== \"object\") {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n if (body.data.type && body.data.type !== \"skill\") {\n return c.json(err(\"INVALID_BODY\", \"body.type does not match route type\"), 400);\n }\n\n try {\n const payload = await installMarketplaceSkill({\n options: this.options,\n body: body.data\n });\n return c.json(ok(payload));\n } catch (error) {\n const message = String(error);\n if (message.startsWith(\"INVALID_BODY:\")) {\n return c.json(err(\"INVALID_BODY\", message.slice(\"INVALID_BODY:\".length)), 400);\n }\n if (message.startsWith(\"NOT_AVAILABLE:\")) {\n return c.json(err(\"NOT_AVAILABLE\", message.slice(\"NOT_AVAILABLE:\".length)), 503);\n }\n return c.json(err(\"INSTALL_FAILED\", message), 400);\n }\n };\n\n readonly manage = async (c: Context) => {\n const body = await readJson<MarketplaceSkillManageRequest>(c.req.raw);\n if (!body.ok || !body.data || typeof body.data !== \"object\") {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n if (body.data.type && body.data.type !== \"skill\") {\n return c.json(err(\"INVALID_BODY\", \"body.type does not match route type\"), 400);\n }\n\n try {\n const payload = await manageMarketplaceSkill({\n options: this.options,\n body: body.data\n });\n return c.json(ok(payload));\n } catch (error) {\n const message = String(error);\n if (message.startsWith(\"INVALID_BODY:\")) {\n return c.json(err(\"INVALID_BODY\", message.slice(\"INVALID_BODY:\".length)), 400);\n }\n if (message.startsWith(\"NOT_AVAILABLE:\")) {\n return c.json(err(\"NOT_AVAILABLE\", message.slice(\"NOT_AVAILABLE:\".length)), 503);\n }\n return c.json(err(\"MANAGE_FAILED\", message), 400);\n }\n };\n\n readonly getRecommendations = async (c: Context) => {\n const query = c.req.query();\n const result = await fetchMarketplaceData<MarketplaceRecommendationView>({\n baseUrl: this.marketplaceBaseUrl,\n path: \"/api/v1/skills/recommendations\",\n query: {\n scene: query.scene,\n limit: query.limit\n }\n });\n\n if (!result.ok) {\n return c.json(err(\"MARKETPLACE_UNAVAILABLE\", result.message), result.status as 500);\n }\n\n const knownSkillNames = collectKnownSkillNames(this.options);\n const filteredItems = sanitizeMarketplaceListItems(result.data.items)\n .map((item) => normalizeMarketplaceItemForUi(item))\n .filter((item) => isSupportedMarketplaceSkillItem(item, knownSkillNames));\n\n return c.json(ok({\n ...result.data,\n total: filteredItems.length,\n items: filteredItems\n }));\n };\n}\n","import type { Hono } from \"hono\";\nimport type { McpMarketplaceController } from \"@nextclaw-server/features/marketplace/controllers/mcp-marketplace.controller.js\";\nimport type { SkillMarketplaceController } from \"@nextclaw-server/features/marketplace/controllers/skill-marketplace.controller.js\";\n\nexport function mountMarketplaceRoutes(\n app: Hono,\n controllers: {\n skill: SkillMarketplaceController;\n mcp: McpMarketplaceController;\n }\n): void {\n app.get(\"/api/marketplace/skills/installed\", controllers.skill.getInstalled);\n app.get(\"/api/marketplace/skills/scenes\", controllers.skill.listScenes);\n app.get(\"/api/marketplace/skills/items\", controllers.skill.listItems);\n app.get(\"/api/marketplace/skills/items/:slug\", controllers.skill.getItem);\n app.get(\"/api/marketplace/skills/items/:slug/content\", controllers.skill.getItemContent);\n app.post(\"/api/marketplace/skills/install\", controllers.skill.install);\n app.post(\"/api/marketplace/skills/manage\", controllers.skill.manage);\n app.get(\"/api/marketplace/skills/recommendations\", controllers.skill.getRecommendations);\n\n app.get(\"/api/marketplace/mcp/installed\", controllers.mcp.getInstalled);\n app.get(\"/api/marketplace/mcp/items\", controllers.mcp.listItems);\n app.get(\"/api/marketplace/mcp/items/:slug\", controllers.mcp.getItem);\n app.get(\"/api/marketplace/mcp/items/:slug/content\", controllers.mcp.getItemContent);\n app.post(\"/api/marketplace/mcp/install\", controllers.mcp.install);\n app.post(\"/api/marketplace/mcp/manage\", controllers.mcp.manage);\n app.post(\"/api/marketplace/mcp/doctor\", controllers.mcp.doctor);\n app.get(\"/api/marketplace/mcp/recommendations\", controllers.mcp.getRecommendations);\n}\n","import * as NextclawCore from \"@nextclaw/core\";\nimport type { NcpSessionSkillsView, SessionSkillEntryView } from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport { loadConfigOrDefault } from \"@nextclaw-server/features/config/index.js\";\nimport type { UiRouterOptions } from \"@nextclaw-server/app/types/router-options.types.js\";\nimport { readNonEmptyString } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport { MARKETPLACE_ZH_COPY_BY_SLUG } from \"@nextclaw-server/features/marketplace/index.js\";\n\ntype SkillInfo = NextclawCore.SkillInfo;\ntype SkillsLoaderInstance = InstanceType<typeof NextclawCore.SkillsLoader>;\n\nconst SCOPE_SORT_ORDER: Record<SessionSkillEntryView[\"scope\"], number> = {\n project: 0,\n workspace: 1,\n builtin: 2,\n};\n\nexport class SessionSkillsViewBuilder {\n constructor(private readonly options: UiRouterOptions) {}\n\n build = (params: {\n sessionId: string;\n sessionMetadata?: Record<string, unknown> | null;\n }): NcpSessionSkillsView => {\n const config = loadConfigOrDefault(this.options.configPath);\n const projectContext = NextclawCore.resolveSessionProjectContext({\n sessionMetadata: params.sessionMetadata,\n workspace: NextclawCore.getWorkspacePathFromConfig(config),\n });\n const skillsLoader = new NextclawCore.SkillsLoader({\n workspace: projectContext.hostWorkspace,\n projectRoot: projectContext.projectRoot,\n });\n const availableRefs = new Set(\n skillsLoader.listSkills(true).map((skill) => skill.ref),\n );\n const records = skillsLoader\n .listSkills(false)\n .map((skill) => this.buildRecord(skill, skillsLoader, availableRefs))\n .sort((left, right) => this.compareRecords(left, right));\n\n return {\n sessionId: params.sessionId,\n total: records.length,\n refs: records.map((record) => record.ref),\n records,\n };\n };\n\n private buildRecord = (\n skill: SkillInfo,\n skillsLoader: SkillsLoaderInstance,\n availableRefs: Set<string>,\n ): SessionSkillEntryView => {\n const metadata = skillsLoader.getSkillMetadata(skill) ?? {};\n const description = readNonEmptyString(metadata.description);\n const descriptionZh =\n readNonEmptyString(metadata.description_zh) ??\n readNonEmptyString(metadata.descriptionZh) ??\n readNonEmptyString(MARKETPLACE_ZH_COPY_BY_SLUG[skill.name]?.description);\n\n return {\n ref: skill.ref,\n name: skill.name,\n path: skill.path,\n scope: skill.scope,\n source: skill.source,\n available: availableRefs.has(skill.ref),\n ...(description ? { description } : {}),\n ...(descriptionZh ? { descriptionZh } : {}),\n };\n };\n\n private compareRecords = (\n left: SessionSkillEntryView,\n right: SessionSkillEntryView,\n ): number => {\n const scopeCompare = SCOPE_SORT_ORDER[left.scope] - SCOPE_SORT_ORDER[right.scope];\n if (scopeCompare !== 0) {\n return scopeCompare;\n }\n const nameCompare = left.name.localeCompare(right.name);\n if (nameCompare !== 0) {\n return nameCompare;\n }\n return left.ref.localeCompare(right.ref);\n };\n}\n","import type { Context } from \"hono\";\nimport type {\n ChatSessionTypesView,\n SessionPatchUpdate,\n UiNcpSessionListView\n} from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport type { NcpSessionSummary } from \"@nextclaw/ncp\";\nimport { applySessionPreferencePatch } from \"@nextclaw-server/features/sessions/utils/session-preference-patch.utils.js\";\nimport {\n isSessionProjectRootValidationError,\n normalizeSessionProjectRoot,\n} from \"@nextclaw-server/features/sessions/utils/session-project-root.utils.js\";\nimport { SessionSkillsViewBuilder } from \"@nextclaw-server/features/sessions/services/session-skills-view.service.js\";\nimport { err, ok, readJson } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport type { UiRouterOptions } from \"@nextclaw-server/app/types/router-options.types.js\";\n\nfunction readPositiveInt(value: string | undefined): number | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const parsed = Number.parseInt(value, 10);\n if (!Number.isFinite(parsed) || parsed <= 0) {\n return undefined;\n }\n return parsed;\n}\n\nfunction readSessionMetadata(\n metadata: unknown,\n): Record<string, unknown> {\n if (!metadata || typeof metadata !== \"object\" || Array.isArray(metadata)) {\n return {};\n }\n return metadata as Record<string, unknown>;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction normalizeIdleSessionActivityPreview(session: NcpSessionSummary): NcpSessionSummary {\n const metadata = readSessionMetadata(session.metadata);\n const preview = metadata.last_activity_preview;\n if (!isRecord(preview) || preview.state !== \"running\") {\n return session;\n }\n return {\n ...session,\n metadata: {\n ...metadata,\n last_activity_preview: {\n ...preview,\n state: \"failed\",\n statusText: \"运行中断:上一轮请求没有完成,请重新发送。\",\n },\n },\n };\n}\n\nfunction applySessionTypePatch(\n metadata: Record<string, unknown>,\n patch: SessionPatchUpdate,\n): Record<string, unknown> {\n if (!Object.prototype.hasOwnProperty.call(patch, \"sessionType\")) {\n return metadata;\n }\n const sessionType = typeof patch.sessionType === \"string\" ? patch.sessionType.trim() : \"\";\n if (sessionType) {\n const { sessionType: _removed, ...nextMetadata } = metadata;\n void _removed;\n return {\n ...nextMetadata,\n session_type: sessionType,\n runtime: sessionType,\n };\n }\n const {\n runtime: _runtime,\n session_type: _sessionType,\n sessionType: _camelSessionType,\n ...nextMetadata\n } = metadata;\n void _runtime;\n void _sessionType;\n void _camelSessionType;\n return nextMetadata;\n}\n\nfunction applyUiReadAtPatch(\n metadata: Record<string, unknown>,\n patch: SessionPatchUpdate,\n): Record<string, unknown> {\n if (!Object.prototype.hasOwnProperty.call(patch, \"uiReadAt\")) {\n return metadata;\n }\n const uiReadAt = typeof patch.uiReadAt === \"string\" ? patch.uiReadAt.trim() : \"\";\n if (uiReadAt) {\n return {\n ...metadata,\n ui_last_read_at: uiReadAt,\n };\n }\n const { ui_last_read_at: _removed, ...nextMetadata } = metadata;\n void _removed;\n return nextMetadata;\n}\n\nfunction applyProjectRootPatch(\n metadata: Record<string, unknown>,\n projectRoot: string | null | undefined,\n): Record<string, unknown> {\n if (projectRoot === undefined) {\n return metadata;\n }\n if (projectRoot) {\n const { projectRoot: _removed, ...nextMetadata } = metadata;\n void _removed;\n return {\n ...nextMetadata,\n project_root: projectRoot,\n };\n }\n const { project_root: _projectRoot, projectRoot: _camelProjectRoot, ...nextMetadata } = metadata;\n void _projectRoot;\n void _camelProjectRoot;\n return nextMetadata;\n}\n\nfunction buildPatchedSessionMetadata(\n metadata: Record<string, unknown>,\n patch: SessionPatchUpdate,\n projectRootPatch: string | null | undefined,\n): Record<string, unknown> {\n const nextMetadata = applySessionPreferencePatch({\n metadata: structuredClone(metadata),\n patch,\n createInvalidThinkingError: () => new Error(\"PREFERRED_THINKING_INVALID\")\n });\n const nextMetadataWithSessionType = applySessionTypePatch(nextMetadata, patch);\n const nextMetadataWithReadAt = applyUiReadAtPatch(nextMetadataWithSessionType, patch);\n return applyProjectRootPatch(nextMetadataWithReadAt, projectRootPatch);\n}\n\nexport class NcpSessionRoutesController {\n private readonly sessionSkillsViewBuilder: SessionSkillsViewBuilder;\n\n constructor(private readonly options: UiRouterOptions) {\n this.sessionSkillsViewBuilder = new SessionSkillsViewBuilder(options);\n }\n\n private readonly withRuntimeStatus = (session: NcpSessionSummary): NcpSessionSummary =>\n this.options.kernel.isSessionRunning(session.sessionId)\n ? { ...session, status: \"running\" }\n : normalizeIdleSessionActivityPreview(session);\n\n readonly getSessionTypes = async (c: Context) => {\n const payload: ChatSessionTypesView = await this.options.kernel.listSessionTypes({\n describeMode: \"observation\",\n });\n return c.json(ok(payload));\n };\n\n readonly listSessions = async (c: Context) => {\n const sessionManager = this.options.kernel.sessionManager;\n const sessions = await sessionManager.listSessions({\n limit: readPositiveInt(c.req.query(\"limit\")),\n peerId: c.req.query(\"peerId\"),\n });\n const payload: UiNcpSessionListView = {\n sessions: sessions.map(this.withRuntimeStatus),\n total: sessions.length,\n };\n return c.json(ok(payload));\n };\n\n readonly getSession = async (c: Context) => {\n const sessionManager = this.options.kernel.sessionManager;\n const sessionId = decodeURIComponent(c.req.param(\"sessionId\"));\n const session = await sessionManager.getSession(sessionId);\n if (!session) {\n return c.json(err(\"NOT_FOUND\", `ncp session not found: ${sessionId}`), 404);\n }\n return c.json(ok(this.withRuntimeStatus(session)));\n };\n\n readonly listSessionMessages = async (c: Context) => {\n const sessionManager = this.options.kernel.sessionManager;\n const sessionId = decodeURIComponent(c.req.param(\"sessionId\"));\n const session = await sessionManager.getSession(sessionId);\n if (!session) {\n return c.json(err(\"NOT_FOUND\", `ncp session not found: ${sessionId}`), 404);\n }\n\n const messages = await sessionManager.listSessionMessages(sessionId, {\n limit: readPositiveInt(c.req.query(\"limit\")),\n });\n const sessionWithRuntimeStatus = this.withRuntimeStatus(session);\n const payload = {\n sessionId,\n status: sessionWithRuntimeStatus.status ?? \"idle\",\n messages,\n ...(sessionWithRuntimeStatus.contextWindow ? { contextWindow: sessionWithRuntimeStatus.contextWindow } : {}),\n total: messages.length,\n };\n return c.json(ok(payload));\n };\n\n readonly getSessionSkills = async (c: Context) => {\n const sessionManager = this.options.kernel.sessionManager;\n const sessionId = decodeURIComponent(c.req.param(\"sessionId\"));\n const query = c.req.query();\n const hasProjectRootOverride = Object.prototype.hasOwnProperty.call(query, \"projectRoot\");\n const existing = await sessionManager.getSession(sessionId);\n const metadata = readSessionMetadata(existing?.metadata);\n\n if (hasProjectRootOverride) {\n try {\n const projectRoot = await normalizeSessionProjectRoot(query.projectRoot);\n if (projectRoot) {\n metadata.project_root = projectRoot;\n } else {\n delete metadata.project_root;\n delete metadata.projectRoot;\n }\n } catch (error) {\n if (isSessionProjectRootValidationError(error)) {\n return c.json(err(error.code, error.message), 400);\n }\n throw error;\n }\n }\n\n return c.json(ok(this.sessionSkillsViewBuilder.build({\n sessionId,\n sessionMetadata: metadata,\n })));\n };\n\n readonly patchSession = async (c: Context) => {\n const sessionManager = this.options.kernel.sessionManager;\n const sessionId = decodeURIComponent(c.req.param(\"sessionId\"));\n const body = await readJson<Record<string, unknown>>(c.req.raw);\n if (!body.ok || !body.data || typeof body.data !== \"object\") {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n\n const patch = body.data as SessionPatchUpdate;\n if (patch.clearHistory) {\n return c.json(err(\"UNSUPPORTED_PATCH\", \"clearHistory is not supported for ncp sessions\"), 400);\n }\n\n let patched;\n try {\n const projectRootPatch = Object.prototype.hasOwnProperty.call(patch, \"projectRoot\")\n ? await normalizeSessionProjectRoot(patch.projectRoot)\n : undefined;\n const existing = await sessionManager.getSessionRecord(sessionId);\n const metadata = buildPatchedSessionMetadata(\n readSessionMetadata(existing?.metadata),\n patch,\n projectRootPatch,\n );\n patched = existing\n ? await sessionManager.setSessionMetadata(sessionId, metadata)\n : Boolean(await sessionManager.updateSession(sessionId, { metadata }));\n } catch (error) {\n if (error instanceof Error && error.message === \"PREFERRED_THINKING_INVALID\") {\n return c.json(err(\"PREFERRED_THINKING_INVALID\", \"preferredThinking must be a supported thinking level\"), 400);\n }\n if (isSessionProjectRootValidationError(error)) {\n return c.json(err(error.code, error.message), 400);\n }\n throw error;\n }\n\n if (!patched) return c.json(err(\"NOT_FOUND\", `ncp session not found: ${sessionId}`), 404);\n\n const updated = await sessionManager.getSession(sessionId);\n if (!updated) {\n return c.json(err(\"NOT_FOUND\", `ncp session not found: ${sessionId}`), 404);\n }\n\n return c.json(ok(this.withRuntimeStatus(updated)));\n };\n\n readonly deleteSession = async (c: Context) => {\n const sessionManager = this.options.kernel.sessionManager;\n const sessionId = decodeURIComponent(c.req.param(\"sessionId\"));\n const existing = await sessionManager.getSession(sessionId);\n if (!existing) {\n return c.json(err(\"NOT_FOUND\", `ncp session not found: ${sessionId}`), 404);\n }\n\n await sessionManager.deleteSession(sessionId);\n return c.json(ok({ deleted: true, sessionId }));\n };\n}\n","import type { Context } from \"hono\";\nimport type {\n RemoteAccountProfileUpdateRequest,\n RemoteBrowserAuthPollRequest,\n RemoteBrowserAuthStartRequest,\n RemoteLoginRequest,\n RemoteServiceAction,\n RemoteSettingsUpdateRequest\n} from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport { err, formatUserFacingError, ok, readJson, readNonEmptyString } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport type { UiRemoteAccessHost } from \"@nextclaw-server/app/types/router-options.types.js\";\n\nconst REMOTE_SERVICE_ACTIONS = new Set<RemoteServiceAction>([\"start\", \"restart\", \"stop\"]);\n\nfunction readTrimmedString(value: unknown): string | undefined {\n return typeof value === \"string\" ? value.trim() : undefined;\n}\n\nexport class RemoteRoutesController {\n constructor(private readonly host: UiRemoteAccessHost) {}\n\n readonly getStatus = async (c: Context) => {\n try {\n return c.json(ok(await this.host.getStatus()));\n } catch (error) {\n return c.json(err(\"REMOTE_STATUS_FAILED\", formatUserFacingError(error)), 500);\n }\n };\n\n readonly getDoctor = async (c: Context) => {\n try {\n return c.json(ok(await this.host.runDoctor()));\n } catch (error) {\n return c.json(err(\"REMOTE_DOCTOR_FAILED\", formatUserFacingError(error)), 500);\n }\n };\n\n readonly login = async (c: Context) => {\n const body = await readJson<RemoteLoginRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n\n const email = readNonEmptyString(body.data.email);\n const password = readNonEmptyString(body.data.password);\n if (!email || !password) {\n return c.json(err(\"INVALID_BODY\", \"email and password are required\"), 400);\n }\n\n try {\n return c.json(ok(await this.host.login({\n email,\n password,\n apiBase: readTrimmedString(body.data.apiBase)\n })));\n } catch (error) {\n return c.json(err(\"REMOTE_LOGIN_FAILED\", formatUserFacingError(error)), 400);\n }\n };\n\n readonly startBrowserAuth = async (c: Context) => {\n const body = await readJson<RemoteBrowserAuthStartRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n\n try {\n return c.json(ok(await this.host.startBrowserAuth({\n apiBase: readTrimmedString(body.data.apiBase)\n })));\n } catch (error) {\n return c.json(err(\"REMOTE_BROWSER_AUTH_START_FAILED\", formatUserFacingError(error)), 400);\n }\n };\n\n readonly pollBrowserAuth = async (c: Context) => {\n const body = await readJson<RemoteBrowserAuthPollRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n\n const sessionId = readNonEmptyString(body.data.sessionId);\n if (!sessionId) {\n return c.json(err(\"INVALID_BODY\", \"sessionId is required\"), 400);\n }\n\n try {\n return c.json(ok(await this.host.pollBrowserAuth({\n sessionId,\n apiBase: readTrimmedString(body.data.apiBase)\n })));\n } catch (error) {\n return c.json(err(\"REMOTE_BROWSER_AUTH_POLL_FAILED\", formatUserFacingError(error)), 400);\n }\n };\n\n readonly logout = async (c: Context) => {\n try {\n return c.json(ok(await this.host.logout()));\n } catch (error) {\n return c.json(err(\"REMOTE_LOGOUT_FAILED\", formatUserFacingError(error)), 500);\n }\n };\n\n readonly updateProfile = async (c: Context) => {\n const body = await readJson<RemoteAccountProfileUpdateRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n\n const username = readNonEmptyString(body.data.username);\n if (!username) {\n return c.json(err(\"INVALID_BODY\", \"username is required\"), 400);\n }\n\n try {\n return c.json(ok(await this.host.updateProfile({ username })));\n } catch (error) {\n return c.json(err(\"REMOTE_PROFILE_UPDATE_FAILED\", formatUserFacingError(error)), 400);\n }\n };\n\n readonly updateSettings = async (c: Context) => {\n const body = await readJson<RemoteSettingsUpdateRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n\n try {\n return c.json(ok(await this.host.updateSettings({\n enabled: typeof body.data.enabled === \"boolean\" ? body.data.enabled : undefined,\n deviceName: readTrimmedString(body.data.deviceName),\n platformApiBase: readTrimmedString(body.data.platformApiBase)\n })));\n } catch (error) {\n return c.json(err(\"REMOTE_SETTINGS_FAILED\", formatUserFacingError(error)), 400);\n }\n };\n\n readonly controlService = async (c: Context) => {\n const action = c.req.param(\"action\");\n if (!REMOTE_SERVICE_ACTIONS.has(action as RemoteServiceAction)) {\n return c.json(err(\"INVALID_ACTION\", \"unsupported remote service action\"), 400);\n }\n\n try {\n return c.json(ok(await this.host.controlService(action as RemoteServiceAction)));\n } catch (error) {\n return c.json(err(\"REMOTE_SERVICE_FAILED\", formatUserFacingError(error)), 400);\n }\n };\n}\n","import type { Context } from \"hono\";\nimport { err, formatUserFacingError, ok } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport type { UiRuntimeControlHost } from \"@nextclaw-server/app/types/router-options.types.js\";\n\nexport class RuntimeControlRoutesController {\n constructor(private readonly host: UiRuntimeControlHost) {}\n\n readonly getControl = async (c: Context) => {\n try {\n return c.json(ok(await this.host.getControl()));\n } catch (error) {\n return c.json(err(\"RUNTIME_CONTROL_FAILED\", formatUserFacingError(error)), 500);\n }\n };\n\n readonly restartService = async (c: Context) => {\n try {\n return c.json(ok(await this.host.restartService()));\n } catch (error) {\n return c.json(err(\"RUNTIME_RESTART_FAILED\", formatUserFacingError(error)), 400);\n }\n };\n\n readonly startService = async (c: Context) => {\n try {\n return c.json(ok(await this.host.startService()));\n } catch (error) {\n return c.json(err(\"RUNTIME_START_FAILED\", formatUserFacingError(error)), 400);\n }\n };\n\n readonly stopService = async (c: Context) => {\n try {\n return c.json(ok(await this.host.stopService()));\n } catch (error) {\n return c.json(err(\"RUNTIME_STOP_FAILED\", formatUserFacingError(error)), 400);\n }\n };\n}\n","import type { Context } from \"hono\";\nimport type { UpdatePreferences, UpdateSnapshot } from \"@nextclaw/shared\";\nimport { err, formatUserFacingError, ok, readJson } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport type { UiRuntimeUpdateHost } from \"@nextclaw-server/app/types/router-options.types.js\";\n\ntype RuntimeUpdatePreferencesRequest = Partial<UpdatePreferences>;\ntype RuntimeUpdateChannelRequest = {\n channel?: UpdateSnapshot[\"channel\"];\n};\n\nexport class RuntimeUpdateRoutesController {\n constructor(private readonly host: UiRuntimeUpdateHost) {}\n\n readonly getState = async (c: Context) => {\n try {\n return c.json(ok(await this.host.getState()));\n } catch (error) {\n return c.json(err(\"RUNTIME_UPDATE_STATE_FAILED\", formatUserFacingError(error)), 500);\n }\n };\n\n readonly checkForUpdates = async (c: Context) => {\n try {\n return c.json(ok(await this.host.checkForUpdates()));\n } catch (error) {\n return c.json(err(\"RUNTIME_UPDATE_CHECK_FAILED\", formatUserFacingError(error)), 400);\n }\n };\n\n readonly downloadUpdate = async (c: Context) => {\n try {\n return c.json(ok(await this.host.downloadUpdate()));\n } catch (error) {\n return c.json(err(\"RUNTIME_UPDATE_DOWNLOAD_FAILED\", formatUserFacingError(error)), 400);\n }\n };\n\n readonly applyDownloadedUpdate = async (c: Context) => {\n try {\n return c.json(ok(await this.host.applyDownloadedUpdate()));\n } catch (error) {\n return c.json(err(\"RUNTIME_UPDATE_APPLY_FAILED\", formatUserFacingError(error)), 400);\n }\n };\n\n readonly updatePreferences = async (c: Context) => {\n const body = await readJson<RuntimeUpdatePreferencesRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n\n try {\n return c.json(ok(await this.host.updatePreferences({\n ...(typeof body.data.automaticChecks === \"boolean\" ? { automaticChecks: body.data.automaticChecks } : {}),\n ...(typeof body.data.autoDownload === \"boolean\" ? { autoDownload: body.data.autoDownload } : {})\n })));\n } catch (error) {\n return c.json(err(\"RUNTIME_UPDATE_PREFERENCES_FAILED\", formatUserFacingError(error)), 400);\n }\n };\n\n readonly updateChannel = async (c: Context) => {\n const body = await readJson<RuntimeUpdateChannelRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n\n const channel = body.data.channel;\n if (channel !== \"stable\" && channel !== \"beta\") {\n return c.json(err(\"INVALID_BODY\", \"channel must be stable or beta\"), 400);\n }\n\n try {\n return c.json(ok(await this.host.updateChannel(channel)));\n } catch (error) {\n return c.json(err(\"RUNTIME_UPDATE_CHANNEL_FAILED\", formatUserFacingError(error)), 400);\n }\n };\n}\n","import type { Context } from \"hono\";\nimport {\n isPanelAppError,\n PanelAppError,\n type PanelAppAgentCapability,\n type PanelAppManager,\n} from \"@nextclaw/kernel\";\nimport type {\n PanelAppAgentGenerateObjectRequestView,\n PanelAppAgentSendRequestView,\n PanelAppBridgeSessionCreateRequest,\n} from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport {\n err,\n isRecord,\n ok,\n readJson,\n} from \"@nextclaw-server/shared/utils/http-response.utils.js\";\n\nconst PANEL_BRIDGE_SESSION_HEADER = \"x-nextclaw-panel-bridge-session\";\n\nfunction createPanelAppResourceHeaders(contentType: string): Record<string, string> {\n return {\n \"content-type\": contentType,\n \"cache-control\": \"no-store\",\n \"access-control-allow-origin\": \"*\",\n };\n}\n\nfunction statusForPanelAppError(code: string): 400 | 401 | 403 | 404 | 408 {\n switch (code) {\n case \"AUTHORIZATION_REQUIRED\":\n return 401;\n case \"PANEL_APP_CAPABILITY_NOT_DECLARED\":\n case \"PANEL_APP_CLIENT_NOT_DECLARED\":\n return 403;\n case \"PANEL_APP_NOT_FOUND\":\n case \"PANEL_APP_BRIDGE_SESSION_NOT_FOUND\":\n return 404;\n case \"PANEL_APP_ASSET_TOKEN_EXPIRED\":\n case \"PANEL_APP_ASSET_TOKEN_INVALID\":\n return 401;\n case \"PANEL_APP_INVALID_ASSET_PATH\":\n case \"PANEL_APP_MANIFEST_INVALID\":\n return 400;\n case \"AGENT_OBJECT_RESULT_TIMEOUT\":\n return 408;\n default:\n return 400;\n }\n}\n\nexport class PanelAppsRoutesController {\n constructor(\n private readonly panelAppManager: PanelAppManager,\n private readonly params: {\n panelAppClientSdkScript?: () => Promise<string> | string;\n } = {},\n ) {}\n\n readonly list = async (c: Context) => {\n const payload = await this.panelAppManager.listPanelApps();\n return c.json(ok(payload));\n };\n\n readonly updatePanelAppPreferences = async (c: Context) => {\n const body = await readJson<unknown>(c.req.raw);\n if (!body.ok || !isRecord(body.data)) {\n return c.json(err(\"INVALID_PANEL_APP_PREFERENCES\", \"invalid panel app preferences\"), 400);\n }\n try {\n const preferences = typeof body.data.favorite === \"boolean\"\n ? { favorite: body.data.favorite }\n : {};\n const payload = await this.panelAppManager.updatePanelAppPreferences(\n c.req.param(\"id\"),\n preferences,\n );\n return c.json(ok(payload));\n } catch (error) {\n if (isPanelAppError(error)) {\n return c.json(\n err(error.code, error.message),\n statusForPanelAppError(error.code),\n );\n }\n throw error;\n }\n };\n\n readonly recordPanelAppOpened = async (c: Context) => {\n try {\n const payload = await this.panelAppManager.recordPanelAppOpened(c.req.param(\"id\"));\n return c.json(ok(payload));\n } catch (error) {\n if (isPanelAppError(error)) {\n return c.json(\n err(error.code, error.message),\n statusForPanelAppError(error.code),\n );\n }\n throw error;\n }\n };\n\n readonly deletePanelApp = async (c: Context) => {\n try {\n const payload = await this.panelAppManager.deletePanelApp(c.req.param(\"id\"));\n return c.json(ok(payload));\n } catch (error) {\n if (isPanelAppError(error)) {\n return c.json(\n err(error.code, error.message),\n statusForPanelAppError(error.code),\n );\n }\n throw error;\n }\n };\n\n readonly getPanelAppContent = async (c: Context): Promise<Response> => {\n try {\n const payload = await this.panelAppManager.getPanelAppContent(\n c.req.param(\"id\"),\n );\n return new Response(payload.html, {\n headers: {\n \"content-type\": payload.contentType,\n \"cache-control\": \"no-store\",\n },\n });\n } catch (error) {\n if (isPanelAppError(error)) {\n return c.json(\n err(error.code, error.message),\n statusForPanelAppError(error.code),\n );\n }\n throw error;\n }\n };\n\n readonly getPanelAppAsset = async (c: Context): Promise<Response> => {\n try {\n const payload = await this.panelAppManager.getPanelAppAsset(\n c.req.param(\"id\"),\n readAssetPath(c.req.raw.url),\n );\n return new Response(payload.content, {\n headers: createPanelAppResourceHeaders(payload.contentType),\n });\n } catch (error) {\n if (isPanelAppError(error)) {\n return c.json(\n err(error.code, error.message),\n statusForPanelAppError(error.code),\n );\n }\n throw error;\n }\n };\n\n readonly getPanelAppAssetByToken = async (c: Context): Promise<Response> => {\n try {\n const payload = await this.panelAppManager.getPanelAppAssetByToken(\n c.req.param(\"token\"),\n readTokenizedAssetPath(c.req.raw.url, c.req.param(\"token\")),\n );\n return new Response(payload.content, {\n headers: createPanelAppResourceHeaders(payload.contentType),\n });\n } catch (error) {\n if (isPanelAppError(error)) {\n return c.json(\n err(error.code, error.message),\n statusForPanelAppError(error.code),\n );\n }\n throw error;\n }\n };\n\n readonly getPanelAppBridgeScript = (): Response => {\n return new Response(this.panelAppManager.getPanelAppBridgeScript(), {\n headers: {\n \"content-type\": \"application/javascript; charset=utf-8\",\n \"cache-control\": \"no-store\",\n },\n });\n };\n\n readonly getPanelAppClientSdkScript = async (): Promise<Response> => {\n if (!this.params.panelAppClientSdkScript) {\n return new Response(\"Panel App client SDK script is not configured.\", {\n status: 404,\n headers: {\n \"content-type\": \"text/plain; charset=utf-8\",\n \"cache-control\": \"no-store\",\n },\n });\n }\n return new Response(await this.params.panelAppClientSdkScript(), {\n headers: createPanelAppResourceHeaders(\"application/javascript; charset=utf-8\"),\n });\n };\n\n readonly createBridgeSession = async (c: Context) => {\n const body = await readJson<PanelAppBridgeSessionCreateRequest>(c.req.raw);\n if (\n !body.ok ||\n !isRecord(body.data) ||\n (typeof body.data.panelAppId !== \"string\" && typeof body.data.appId !== \"string\")\n ) {\n return c.json(err(\"INVALID_PANEL_APP_BRIDGE_SESSION\", \"invalid bridge session request\"), 400);\n }\n const panelAppId = typeof body.data.appId === \"string\"\n ? body.data.appId\n : body.data.panelAppId;\n if (typeof panelAppId !== \"string\") {\n return c.json(err(\"INVALID_PANEL_APP_BRIDGE_SESSION\", \"invalid bridge session request\"), 400);\n }\n try {\n const session = await this.panelAppManager.createPanelAppBridgeSession({\n id: panelAppId,\n });\n return c.json(ok({\n id: session.id,\n token: session.token,\n appId: session.appId,\n expiresAt: session.expiresAt,\n }));\n } catch (error) {\n if (isPanelAppError(error)) {\n return c.json(\n err(error.code, error.message),\n statusForPanelAppError(error.code),\n );\n }\n throw error;\n }\n };\n\n readonly deleteBridgeSession = (c: Context) => {\n this.panelAppManager.deletePanelAppBridgeSession(c.req.param(\"token\"));\n return c.json(ok({ deleted: true }));\n };\n\n readonly grantClient = async (c: Context) => {\n try {\n return c.json(ok(await this.panelAppManager.grantPanelAppClient(\n c.req.param(\"appId\"),\n )));\n } catch (error) {\n return this.handlePanelAppError(c, error);\n }\n };\n\n readonly revokeClient = async (c: Context) => {\n try {\n await this.panelAppManager.revokePanelAppClient(c.req.param(\"appId\"));\n return c.json(ok({ revoked: true }));\n } catch (error) {\n return this.handlePanelAppError(c, error);\n }\n };\n\n readonly sendAgentMessage = async (c: Context) => {\n const body = await readJson<PanelAppAgentSendRequestView>(c.req.raw);\n if (!body.ok || !isRecord(body.data) || !isRecord(body.data.payload)) {\n return c.json(err(\"INVALID_PANEL_APP_AGENT_REQUEST\", \"invalid agent send request\"), 400);\n }\n try {\n return c.json(ok(await this.panelAppManager.sendAgentMessage(\n this.requireBridgeSessionToken(c),\n body.data.payload,\n )));\n } catch (error) {\n return this.handlePanelAppError(c, error);\n }\n };\n\n readonly generateAgentObject = async (c: Context) => {\n const body = await readJson<PanelAppAgentGenerateObjectRequestView>(c.req.raw);\n if (!body.ok || !isRecord(body.data) || !isRecord(body.data.input)) {\n return c.json(err(\"INVALID_PANEL_APP_AGENT_REQUEST\", \"invalid generateObject request\"), 400);\n }\n try {\n return c.json(ok(await this.panelAppManager.generateAgentObject(\n this.requireBridgeSessionToken(c),\n body.data.input,\n )));\n } catch (error) {\n return this.handlePanelAppError(c, error);\n }\n };\n\n readonly grantAgentCapability = async (c: Context) => {\n try {\n return c.json(ok(await this.panelAppManager.grantAgentCapability(\n this.requireBridgeSessionToken(c),\n c.req.param(\"capability\") as PanelAppAgentCapability,\n )));\n } catch (error) {\n return this.handlePanelAppError(c, error);\n }\n };\n\n private requireBridgeSessionToken = (c: Context): string => {\n const token = c.req.raw.headers.get(PANEL_BRIDGE_SESSION_HEADER)?.trim();\n if (!token) {\n throw new Error(\"panel app bridge session is required\");\n }\n return token;\n };\n\n private handlePanelAppError = (c: Context, error: unknown) => {\n if (isPanelAppError(error)) {\n return c.json(\n err(error.code, error.message),\n statusForPanelAppError(error.code),\n );\n }\n if (error instanceof Error && error.message === \"panel app bridge session is required\") {\n return c.json(err(\"PANEL_APP_BRIDGE_SESSION_REQUIRED\", error.message), 401);\n }\n throw error;\n };\n}\n\nfunction readAssetPath(url: string): string {\n const pathname = new URL(url).pathname;\n const marker = \"/assets/\";\n const markerIndex = pathname.indexOf(marker);\n if (markerIndex < 0) {\n return \"\";\n }\n try {\n return decodeURIComponent(pathname.slice(markerIndex + marker.length));\n } catch {\n throw new PanelAppError(\"PANEL_APP_INVALID_ASSET_PATH\", \"invalid panel app asset path\");\n }\n}\n\nfunction readTokenizedAssetPath(url: string, token: string): string {\n const pathname = new URL(url).pathname;\n const marker = `/api/panel-app-assets/${encodeURIComponent(token)}/`;\n if (!pathname.startsWith(marker)) {\n return \"\";\n }\n try {\n return decodeURIComponent(pathname.slice(marker.length));\n } catch {\n throw new PanelAppError(\"PANEL_APP_INVALID_ASSET_PATH\", \"invalid panel app asset path\");\n }\n}\n","import type { Context } from \"hono\";\nimport {\n isPreferenceError,\n type PreferenceManager,\n} from \"@nextclaw/kernel\";\nimport type {\n PreferenceDeleteResult,\n PreferenceEntryView,\n PreferenceUpdateRequest,\n} from \"@nextclaw-server/features/preferences/types/preferences-api.types.js\";\nimport {\n err,\n isRecord,\n ok,\n readJson,\n} from \"@nextclaw-server/shared/utils/http-response.utils.js\";\n\nfunction statusForPreferenceError(code: string): 400 {\n void code;\n return 400;\n}\n\nexport class PreferencesRoutesController {\n constructor(private readonly preferenceManager: PreferenceManager) {}\n\n readonly get = async (c: Context) => {\n try {\n const entry = await this.preferenceManager.getPreference(c.req.param(\"key\"));\n const payload: PreferenceEntryView = entry\n ? {\n key: entry.key,\n value: entry.value,\n updatedAt: entry.updatedAt,\n }\n : {\n key: c.req.param(\"key\"),\n value: null,\n };\n return c.json(ok(payload));\n } catch (error) {\n if (isPreferenceError(error)) {\n return c.json(\n err(error.code, error.message),\n statusForPreferenceError(error.code),\n );\n }\n throw error;\n }\n };\n\n readonly update = async (c: Context) => {\n const body = await readJson<PreferenceUpdateRequest>(c.req.raw);\n if (!body.ok || !isRecord(body.data) || !Object.hasOwn(body.data, \"value\")) {\n return c.json(err(\"INVALID_PREFERENCE\", \"preference value is required\"), 400);\n }\n try {\n const entry = await this.preferenceManager.setPreference(\n c.req.param(\"key\"),\n body.data.value,\n );\n return c.json(ok({\n key: entry.key,\n value: entry.value,\n updatedAt: entry.updatedAt,\n } satisfies PreferenceEntryView));\n } catch (error) {\n if (isPreferenceError(error)) {\n return c.json(\n err(error.code, error.message),\n statusForPreferenceError(error.code),\n );\n }\n throw error;\n }\n };\n\n readonly delete = async (c: Context) => {\n try {\n const key = c.req.param(\"key\");\n const deleted = await this.preferenceManager.deletePreference(key);\n return c.json(ok({\n key,\n deleted,\n } satisfies PreferenceDeleteResult));\n } catch (error) {\n if (isPreferenceError(error)) {\n return c.json(\n err(error.code, error.message),\n statusForPreferenceError(error.code),\n );\n }\n throw error;\n }\n };\n}\n","import type { Context } from \"hono\";\nimport {\n isPanelAppError,\n isServiceAppError,\n type PanelAppManager,\n type ServiceAppManager,\n} from \"@nextclaw/kernel\";\nimport {\n err,\n isRecord,\n ok,\n readJson,\n} from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport type {\n ServiceActionGrantBatchRequestView,\n ServiceActionInvokeRequestView,\n} from \"@nextclaw-server/shared/types/server-api.types.js\";\n\nconst PANEL_BRIDGE_SESSION_HEADER = \"x-nextclaw-panel-bridge-session\";\n\nfunction statusForServiceAppError(code: string): 400 | 401 | 403 | 404 {\n switch (code) {\n case \"AUTHORIZATION_REQUIRED\":\n return 401;\n case \"SERVICE_APP_ACTION_NOT_DECLARED\":\n return 403;\n case \"SERVICE_APP_ACTION_NOT_FOUND\":\n case \"SERVICE_APP_NOT_FOUND\":\n return 404;\n default:\n return 400;\n }\n}\n\nexport class ServiceAppsRoutesController {\n constructor(private readonly params: {\n panelAppManager: PanelAppManager;\n serviceAppManager: ServiceAppManager;\n }) {}\n\n readonly listServiceApps = async (c: Context) => {\n return c.json(ok(await this.params.serviceAppManager.listServiceApps()));\n };\n\n readonly getServiceApp = async (c: Context) => {\n try {\n return c.json(ok(await this.params.serviceAppManager.getServiceApp(c.req.param(\"appId\"))));\n } catch (error) {\n return this.handleServiceAppError(c, error);\n }\n };\n\n readonly listServiceActions = async (c: Context) => {\n try {\n const bridgeSession = this.readOptionalBridgeSession(c);\n const appId = c.req.query(\"appId\")?.trim();\n const actions = await this.params.serviceAppManager.listServiceActions(\n bridgeSession\n ? {\n caller: bridgeSession.caller,\n appId,\n declaredActions: bridgeSession.declaredActions,\n }\n : { appId },\n );\n return c.json(ok({ actions }));\n } catch (error) {\n return this.handleServiceAppError(c, error);\n }\n };\n\n readonly discoverServiceAppActions = async (c: Context) => {\n try {\n const actions = await this.params.serviceAppManager.discoverServiceAppActions(\n c.req.param(\"appId\"),\n );\n return c.json(ok({ actions }));\n } catch (error) {\n return this.handleServiceAppError(c, error);\n }\n };\n\n readonly invokeServiceAction = async (c: Context) => {\n const body = await readJson<ServiceActionInvokeRequestView>(c.req.raw);\n if (!body.ok || (body.data !== undefined && !isRecord(body.data))) {\n return c.json(err(\"INVALID_SERVICE_ACTION_REQUEST\", \"invalid service action request\"), 400);\n }\n try {\n const bridgeSession = this.requireBridgeSession(c);\n const payload = await this.params.serviceAppManager.invokeServiceAction(\n c.req.param(\"actionId\"),\n {\n caller: bridgeSession.caller,\n declaredActions: bridgeSession.declaredActions,\n input: isRecord(body.data.input) ? body.data.input : {},\n },\n );\n return c.json(ok(payload));\n } catch (error) {\n return this.handleServiceAppError(c, error);\n }\n };\n\n readonly grantServiceAction = async (c: Context) => {\n try {\n const bridgeSession = this.requireBridgeSession(c);\n const payload = await this.params.serviceAppManager.grantServiceAction(\n c.req.param(\"actionId\"),\n {\n caller: bridgeSession.caller,\n declaredActions: bridgeSession.declaredActions,\n },\n );\n return c.json(ok(payload));\n } catch (error) {\n return this.handleServiceAppError(c, error);\n }\n };\n\n readonly grantServiceActions = async (c: Context) => {\n const body = await readJson<ServiceActionGrantBatchRequestView>(c.req.raw);\n if (!body.ok || !Array.isArray(body.data?.actionIds)) {\n return c.json(err(\"INVALID_SERVICE_ACTION_GRANT_REQUEST\", \"invalid service action grant request\"), 400);\n }\n try {\n const bridgeSession = this.requireBridgeSession(c);\n const grants = await this.params.serviceAppManager.grantServiceActions(\n body.data.actionIds,\n {\n caller: bridgeSession.caller,\n declaredActions: bridgeSession.declaredActions,\n },\n );\n return c.json(ok({ grants }));\n } catch (error) {\n return this.handleServiceAppError(c, error);\n }\n };\n\n readonly listServiceActionGrants = async (c: Context) => {\n return c.json(ok({\n grants: await this.params.serviceAppManager.listServiceActionGrants(),\n }));\n };\n\n readonly revokeServiceAction = async (c: Context) => {\n try {\n const bridgeSession = this.requireBridgeSession(c);\n await this.params.serviceAppManager.revokeServiceAction(\n bridgeSession.caller,\n c.req.param(\"actionId\"),\n );\n return c.json(ok({ revoked: true }));\n } catch (error) {\n return this.handleServiceAppError(c, error);\n }\n };\n\n readonly revokeServiceActionGrant = async (c: Context) => {\n const caller = this.readCallerQuery(c);\n if (!caller) {\n return c.json(err(\"INVALID_SERVICE_ACTION_CALLER\", \"invalid service action caller\"), 400);\n }\n try {\n await this.params.serviceAppManager.revokeServiceAction(\n caller,\n c.req.param(\"actionId\"),\n );\n return c.json(ok({ revoked: true }));\n } catch (error) {\n return this.handleServiceAppError(c, error);\n }\n };\n\n readonly restartServiceApp = async (c: Context) => {\n try {\n return c.json(ok(await this.params.serviceAppManager.restartServiceApp(c.req.param(\"appId\"))));\n } catch (error) {\n return this.handleServiceAppError(c, error);\n }\n };\n\n readonly deleteServiceApp = async (c: Context) => {\n try {\n return c.json(ok(await this.params.serviceAppManager.deleteServiceApp(c.req.param(\"appId\"))));\n } catch (error) {\n return this.handleServiceAppError(c, error);\n }\n };\n\n private requireBridgeSession = (c: Context) => {\n const token = c.req.raw.headers.get(PANEL_BRIDGE_SESSION_HEADER)?.trim();\n if (!token) {\n throw new Error(\"panel app bridge session is required\");\n }\n return this.params.panelAppManager.resolvePanelAppBridgeSession(token);\n };\n\n private readOptionalBridgeSession = (c: Context) => {\n const token = c.req.raw.headers.get(PANEL_BRIDGE_SESSION_HEADER)?.trim();\n return token\n ? this.params.panelAppManager.resolvePanelAppBridgeSession(token)\n : null;\n };\n\n private readCallerQuery = (c: Context) => {\n const surface = c.req.query(\"surface\");\n const appId = c.req.query(\"appId\")?.trim();\n if (surface !== \"panel-app\" || !appId) {\n return null;\n }\n return { surface, appId } as const;\n };\n\n private handleServiceAppError = (c: Context, error: unknown) => {\n if (isServiceAppError(error)) {\n return c.json(\n err(error.code, error.message),\n statusForServiceAppError(error.code),\n );\n }\n if (isPanelAppError(error)) {\n return c.json(err(error.code, error.message), 404);\n }\n if (error instanceof Error && error.message === \"panel app bridge session is required\") {\n return c.json(err(\"PANEL_APP_BRIDGE_SESSION_REQUIRED\", error.message), 401);\n }\n throw error;\n };\n}\n","import type { NcpEndpointEvent, NcpStreamRequestPayload } from \"@nextclaw/ncp\";\nimport { eventKeys, type EventBus, type Unsubscribe } from \"@nextclaw/shared\";\n\nfunction readEventSessionId(event: NcpEndpointEvent): string | null {\n const payload = \"payload\" in event ? event.payload : null;\n if (!payload || typeof payload !== \"object\") {\n return null;\n }\n return \"sessionId\" in payload && typeof payload.sessionId === \"string\"\n ? payload.sessionId\n : null;\n}\n\nfunction toSseFrame(eventName: string, data: unknown): string {\n return `event: ${eventName}\\ndata: ${JSON.stringify(data)}\\n\\n`;\n}\n\nexport function createNcpSessionEventStreamResponse(\n eventBus: Pick<EventBus, \"on\">,\n payload: NcpStreamRequestPayload,\n signal: AbortSignal,\n): Response {\n const encoder = new TextEncoder();\n let controller: ReadableStreamDefaultController<Uint8Array> | null = null;\n let closed = false;\n let unsubscribe: Unsubscribe = () => undefined;\n const cleanup = () => {\n unsubscribe();\n signal.removeEventListener(\"abort\", close);\n };\n const close = () => {\n if (closed) {\n return;\n }\n closed = true;\n cleanup();\n controller?.close();\n };\n const push = (event: NcpEndpointEvent) => {\n if (closed || signal.aborted) {\n return;\n }\n if (readEventSessionId(event) === payload.sessionId) {\n controller?.enqueue(encoder.encode(toSseFrame(\"ncp-event\", event)));\n }\n };\n const stream = new ReadableStream<Uint8Array>({\n start: (streamController) => {\n controller = streamController;\n unsubscribe = eventBus.on(eventKeys.ncpEvent, push);\n signal.addEventListener(\"abort\", close, { once: true });\n if (signal.aborted) {\n close();\n }\n },\n cancel: () => {\n if (!closed) {\n closed = true;\n cleanup();\n }\n },\n });\n return new Response(stream, {\n headers: {\n \"Content-Type\": \"text/event-stream; charset=utf-8\",\n \"Cache-Control\": \"no-cache, no-transform\",\n Connection: \"keep-alive\",\n \"X-Accel-Buffering\": \"no\",\n },\n });\n}\n","import { readdir, stat } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, parse, resolve } from \"node:path\";\nimport { expandHome } from \"@nextclaw/core\";\nimport type {\n ServerPathBreadcrumbView,\n ServerPathBrowseView,\n ServerPathEntryView,\n} from \"@nextclaw-server/shared/types/server-api.types.js\";\n\ntype BrowseServerPathOptions = {\n path?: string | null;\n includeFiles?: boolean;\n};\n\ntype ServerPathBrowseErrorCode =\n | \"SERVER_PATH_NOT_FOUND\"\n | \"SERVER_PATH_NOT_DIRECTORY\"\n | \"SERVER_PATH_NOT_READABLE\";\n\nexport class ServerPathBrowseError extends Error {\n constructor(\n readonly code: ServerPathBrowseErrorCode,\n message: string,\n ) {\n super(message);\n this.name = \"ServerPathBrowseError\";\n }\n}\n\nfunction normalizeBrowsePath(path?: string | null): string {\n const trimmed = typeof path === \"string\" ? path.trim() : \"\";\n return resolve(expandHome(trimmed || homedir()));\n}\n\nfunction readRootLabel(rootPath: string): string {\n const normalized = rootPath.replace(/[\\\\/]+$/, \"\");\n return normalized || rootPath;\n}\n\nfunction buildBreadcrumbs(currentPath: string): ServerPathBreadcrumbView[] {\n const parsedPath = parse(currentPath);\n const rootPath = parsedPath.root || currentPath;\n const rootBreadcrumb: ServerPathBreadcrumbView = {\n label: readRootLabel(rootPath),\n path: rootPath,\n };\n const relativeSegments = currentPath\n .slice(rootPath.length)\n .split(/[\\\\/]+/)\n .filter(Boolean);\n\n const breadcrumbs = [rootBreadcrumb];\n let breadcrumbPath = rootPath;\n for (const segment of relativeSegments) {\n breadcrumbPath = resolve(breadcrumbPath, segment);\n breadcrumbs.push({\n label: segment,\n path: breadcrumbPath,\n });\n }\n return breadcrumbs;\n}\n\nasync function resolveEntryView(params: {\n parentPath: string;\n entryName: string;\n includeFiles: boolean;\n}): Promise<ServerPathEntryView | null> {\n const { parentPath, entryName, includeFiles } = params;\n const entryPath = resolve(parentPath, entryName);\n let entryStats;\n try {\n entryStats = await stat(entryPath);\n } catch {\n return null;\n }\n\n const isDirectory = entryStats.isDirectory();\n if (!isDirectory && !includeFiles) {\n return null;\n }\n\n return {\n name: entryName,\n path: entryPath,\n kind: isDirectory ? \"directory\" : \"file\",\n hidden: entryName.startsWith(\".\"),\n };\n}\n\nfunction sortEntryViews(left: ServerPathEntryView, right: ServerPathEntryView): number {\n if (left.kind !== right.kind) {\n return left.kind === \"directory\" ? -1 : 1;\n }\n return left.name.localeCompare(right.name);\n}\n\nexport async function browseServerPath(\n options: BrowseServerPathOptions = {},\n): Promise<ServerPathBrowseView> {\n const currentPath = normalizeBrowsePath(options.path);\n\n let currentPathStats;\n try {\n currentPathStats = await stat(currentPath);\n } catch {\n throw new ServerPathBrowseError(\n \"SERVER_PATH_NOT_FOUND\",\n \"server path does not exist\",\n );\n }\n if (!currentPathStats.isDirectory()) {\n throw new ServerPathBrowseError(\n \"SERVER_PATH_NOT_DIRECTORY\",\n \"server path must point to a directory\",\n );\n }\n\n let entryNames: string[];\n try {\n entryNames = await readdir(currentPath);\n } catch {\n throw new ServerPathBrowseError(\n \"SERVER_PATH_NOT_READABLE\",\n \"server path is not readable\",\n );\n }\n\n const entries = (\n await Promise.all(\n entryNames.map((entryName) =>\n resolveEntryView({\n parentPath: currentPath,\n entryName,\n includeFiles: options.includeFiles ?? false,\n }),\n ),\n )\n )\n .filter((entry): entry is ServerPathEntryView => entry !== null)\n .sort(sortEntryViews);\n\n const parentPath = dirname(currentPath);\n\n return {\n currentPath,\n parentPath: parentPath === currentPath ? null : parentPath,\n homePath: resolve(homedir()),\n breadcrumbs: buildBreadcrumbs(currentPath),\n entries,\n };\n}\n\nexport function isServerPathBrowseError(\n error: unknown,\n): error is ServerPathBrowseError {\n return error instanceof ServerPathBrowseError;\n}\n","import { open, stat } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { extname, resolve } from \"node:path\";\nimport { expandHome } from \"@nextclaw/core\";\nimport type { ServerPathReadView } from \"@nextclaw-server/shared/types/server-api.types.js\";\n\ntype ReadServerPathOptions = {\n path?: string | null;\n basePath?: string | null;\n maxBytes?: number;\n};\n\ntype ServerPathReadErrorCode =\n | \"SERVER_PATH_BASE_REQUIRED\"\n | \"SERVER_PATH_NOT_FOUND\"\n | \"SERVER_PATH_NOT_FILE\"\n | \"SERVER_PATH_NOT_READABLE\";\n\nconst DEFAULT_PREVIEW_MAX_BYTES = 200_000;\nconst MARKDOWN_EXTENSIONS = new Set([\".md\", \".mdx\", \".markdown\"]);\nconst TEXT_EXTENSIONS = new Set([\n \".c\",\n \".cc\",\n \".conf\",\n \".cpp\",\n \".css\",\n \".csv\",\n \".env\",\n \".go\",\n \".graphql\",\n \".h\",\n \".hpp\",\n \".html\",\n \".ini\",\n \".java\",\n \".js\",\n \".json\",\n \".jsx\",\n \".log\",\n \".mjs\",\n \".py\",\n \".rb\",\n \".rs\",\n \".sh\",\n \".sql\",\n \".svg\",\n \".toml\",\n \".ts\",\n \".tsx\",\n \".txt\",\n \".xml\",\n \".yaml\",\n \".yml\",\n]);\n\nexport class ServerPathReadError extends Error {\n constructor(\n readonly code: ServerPathReadErrorCode,\n message: string,\n ) {\n super(message);\n this.name = \"ServerPathReadError\";\n }\n}\n\nfunction normalizeReadPath(params: {\n path?: string | null;\n basePath?: string | null;\n}): string {\n const { basePath, path } = params;\n const rawPath = typeof path === \"string\" ? path.trim() : \"\";\n const normalizedBasePath =\n typeof basePath === \"string\" ? basePath.trim() : \"\";\n if (!rawPath) {\n return resolve(expandHome(normalizedBasePath || homedir()));\n }\n const expandedPath = expandHome(rawPath);\n if (expandedPath.startsWith(\"/\")) {\n return resolve(expandedPath);\n }\n if (!normalizedBasePath) {\n throw new ServerPathReadError(\n \"SERVER_PATH_BASE_REQUIRED\",\n \"relative server path requires a base path\",\n );\n }\n const resolvedBasePath = expandHome(normalizedBasePath);\n return resolve(resolvedBasePath, expandedPath);\n}\n\nfunction inferPreviewKind(path: string): \"markdown\" | \"text\" | \"binary\" {\n const extension = extname(path).toLowerCase();\n if (MARKDOWN_EXTENSIONS.has(extension)) {\n return \"markdown\";\n }\n if (TEXT_EXTENSIONS.has(extension)) {\n return \"text\";\n }\n return \"binary\";\n}\n\nfunction isLikelyTextBuffer(buffer: Buffer): boolean {\n for (const byte of buffer) {\n if (byte === 0) {\n return false;\n }\n }\n return true;\n}\n\nfunction readLanguageHint(path: string): string | null {\n const extension = extname(path).toLowerCase();\n if (!extension) {\n return null;\n }\n if (MARKDOWN_EXTENSIONS.has(extension)) {\n return \"markdown\";\n }\n return extension.slice(1) || null;\n}\n\nasync function readFilePreviewBytes(params: {\n resolvedPath: string;\n sizeBytes: number;\n maxBytes: number;\n}): Promise<{ buffer: Buffer; truncated: boolean }> {\n const { maxBytes, resolvedPath, sizeBytes } = params;\n const bytesToRead = Math.min(sizeBytes, maxBytes);\n const fileHandle = await open(resolvedPath, \"r\");\n try {\n const buffer = Buffer.alloc(bytesToRead);\n const { bytesRead } = await fileHandle.read(buffer, 0, bytesToRead, 0);\n return {\n buffer: buffer.subarray(0, bytesRead),\n truncated: sizeBytes > maxBytes,\n };\n } finally {\n await fileHandle.close();\n }\n}\n\nexport async function readServerPath(\n options: ReadServerPathOptions = {},\n): Promise<ServerPathReadView> {\n const requestedPath = typeof options.path === \"string\" ? options.path.trim() : \"\";\n const resolvedPath = normalizeReadPath(options);\n\n let resolvedStats;\n try {\n resolvedStats = await stat(resolvedPath);\n } catch {\n throw new ServerPathReadError(\n \"SERVER_PATH_NOT_FOUND\",\n \"server path does not exist\",\n );\n }\n if (!resolvedStats.isFile()) {\n throw new ServerPathReadError(\n \"SERVER_PATH_NOT_FILE\",\n \"server path must point to a file\",\n );\n }\n\n let previewBytes;\n try {\n previewBytes = await readFilePreviewBytes({\n resolvedPath,\n sizeBytes: resolvedStats.size,\n maxBytes: options.maxBytes ?? DEFAULT_PREVIEW_MAX_BYTES,\n });\n } catch {\n throw new ServerPathReadError(\n \"SERVER_PATH_NOT_READABLE\",\n \"server path is not readable\",\n );\n }\n\n const inferredKind = inferPreviewKind(resolvedPath);\n const resolvedKind =\n inferredKind === \"binary\" && isLikelyTextBuffer(previewBytes.buffer)\n ? \"text\"\n : inferredKind;\n\n if (resolvedKind === \"binary\") {\n return {\n requestedPath: requestedPath || resolvedPath,\n resolvedPath,\n kind: \"binary\",\n sizeBytes: resolvedStats.size,\n truncated: previewBytes.truncated,\n languageHint: readLanguageHint(resolvedPath),\n };\n }\n\n return {\n requestedPath: requestedPath || resolvedPath,\n resolvedPath,\n kind: resolvedKind,\n sizeBytes: resolvedStats.size,\n truncated: previewBytes.truncated,\n text: previewBytes.buffer.toString(\"utf8\"),\n languageHint: readLanguageHint(resolvedPath),\n };\n}\n\nexport function isServerPathReadError(\n error: unknown,\n): error is ServerPathReadError {\n return error instanceof ServerPathReadError;\n}\n","import type { Context } from \"hono\";\nimport type { ServerPathBrowseView, ServerPathReadView } from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport {\n browseServerPath,\n isServerPathBrowseError,\n} from \"@nextclaw-server/features/server-path/utils/server-path-browse.utils.js\";\nimport {\n isServerPathReadError,\n readServerPath,\n} from \"@nextclaw-server/features/server-path/utils/server-path-read.utils.js\";\nimport { err, ok } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\n\nfunction readIncludeFilesFlag(value: string | undefined): boolean {\n return value === \"1\" || value === \"true\";\n}\n\nexport class ServerPathRoutesController {\n readonly browse = async (c: Context) => {\n try {\n const payload: ServerPathBrowseView = await browseServerPath({\n path: c.req.query(\"path\"),\n includeFiles: readIncludeFilesFlag(c.req.query(\"includeFiles\")),\n });\n return c.json(ok(payload));\n } catch (error) {\n if (isServerPathBrowseError(error)) {\n return c.json(err(error.code, error.message), 400);\n }\n throw error;\n }\n };\n\n readonly read = async (c: Context) => {\n try {\n const payload: ServerPathReadView = await readServerPath({\n path: c.req.query(\"path\"),\n basePath: c.req.query(\"basePath\"),\n });\n return c.json(ok(payload));\n } catch (error) {\n if (isServerPathReadError(error)) {\n return c.json(err(error.code, error.message), 400);\n }\n throw error;\n }\n };\n}\n","import { Hono, type Handler } from \"hono\";\nimport type {\n NcpMessageAbortPayload,\n NcpRunHandle,\n NcpStreamRequestPayload,\n} from \"@nextclaw/ncp\";\nimport { AccessManager } from \"@nextclaw/kernel\";\nimport {\n ingressKeys,\n type AgentRunSendIngressPayload,\n type IngressEnvelope,\n} from \"@nextclaw/shared\";\nimport { AgentsRoutesController } from \"@nextclaw-server/features/agents/index.js\";\nimport { AppRoutesController } from \"@nextclaw-server/app/controllers/app.controller.js\";\nimport { AuthRoutesController, UiAuthService } from \"@nextclaw-server/features/auth/index.js\";\nimport { ConfigRoutesController } from \"@nextclaw-server/features/config/index.js\";\nimport { CronRoutesController } from \"@nextclaw-server/features/cron/index.js\";\nimport { NcpAssetRoutesController } from \"@nextclaw-server/features/attachments/index.js\";\nimport { NcpSessionRoutesController } from \"@nextclaw-server/features/sessions/index.js\";\nimport {\n McpMarketplaceController,\n mountMarketplaceRoutes,\n normalizeMarketplaceBaseUrl,\n SkillMarketplaceController\n} from \"@nextclaw-server/features/marketplace/index.js\";\nimport { RemoteRoutesController } from \"@nextclaw-server/features/remote-access/index.js\";\nimport { RuntimeControlRoutesController } from \"@nextclaw-server/features/runtime-control/index.js\";\nimport { RuntimeUpdateRoutesController } from \"@nextclaw-server/features/runtime-update/index.js\";\nimport { PanelAppsRoutesController } from \"@nextclaw-server/features/panel-apps/index.js\";\nimport { PreferencesRoutesController } from \"@nextclaw-server/features/preferences/index.js\";\nimport { ServiceAppsRoutesController } from \"@nextclaw-server/features/service-apps/index.js\";\nimport { err, ok, readJson } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport { createNcpSessionEventStreamResponse } from \"@nextclaw-server/app/utils/ncp-session-event-stream.utils.js\";\nimport { ServerPathRoutesController } from \"@nextclaw-server/features/server-path/index.js\";\nimport type { UiRouterOptions } from \"@nextclaw-server/app/types/router-options.types.js\";\n\nconst NCP_AGENT_BASE_PATH = \"/api/ncp/agent\";\nconst AGENT_RUNS_BASE_PATH = \"/api/agent-runs\";\n\nfunction createUiRouteControllers(\n options: UiRouterOptions,\n authService: UiAuthService,\n marketplaceBaseUrl: string\n) {\n const {\n kernel,\n panelAppClientSdkScript,\n remoteAccess,\n runtimeControl,\n runtimeUpdate,\n } = options;\n return {\n app: new AppRoutesController(options),\n agents: new AgentsRoutesController(options),\n auth: new AuthRoutesController(authService),\n config: new ConfigRoutesController(options),\n cron: new CronRoutesController(options),\n ncpSession: new NcpSessionRoutesController(options),\n ncpAsset: new NcpAssetRoutesController(options),\n panelApps: new PanelAppsRoutesController(kernel.panelAppManager, {\n panelAppClientSdkScript,\n }),\n preferences: new PreferencesRoutesController(kernel.preferenceManager),\n serviceApps: new ServiceAppsRoutesController({\n panelAppManager: kernel.panelAppManager,\n serviceAppManager: kernel.serviceAppManager,\n }),\n serverPath: new ServerPathRoutesController(),\n remote: remoteAccess ? new RemoteRoutesController(remoteAccess) : null,\n runtimeControl: runtimeControl ? new RuntimeControlRoutesController(runtimeControl) : null,\n runtimeUpdate: runtimeUpdate ? new RuntimeUpdateRoutesController(runtimeUpdate) : null,\n skillMarketplace: new SkillMarketplaceController(options, marketplaceBaseUrl),\n mcpMarketplace: new McpMarketplaceController(options, marketplaceBaseUrl)\n };\n}\n\ntype UiRouteControllers = ReturnType<typeof createUiRouteControllers>;\ntype HttpMethod = \"delete\" | \"get\" | \"patch\" | \"post\" | \"put\";\ntype RouteDefinition = readonly [HttpMethod, string, Handler];\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction hasOwn(value: Record<string, unknown>, key: string): boolean {\n return Object.prototype.hasOwnProperty.call(value, key);\n}\n\nfunction isValidSendEnvelope(value: unknown): value is AgentRunSendIngressPayload {\n if (!isRecord(value)) {\n return false;\n }\n const sessionId = readOptionalSendIdentity(value, \"sessionId\");\n const peerId = readOptionalSendIdentity(value, \"peerId\");\n if (sessionId === null || peerId === null || (sessionId && peerId)) {\n return false;\n }\n const hasMessage = hasOwn(value, \"message\");\n const hasContent = hasOwn(value, \"content\");\n if (hasMessage === hasContent) {\n return false;\n }\n return hasMessage ? isRecord(value.message) : Array.isArray(value.content);\n}\n\nfunction readOptionalSendIdentity(\n value: Record<string, unknown>,\n key: \"peerId\" | \"sessionId\",\n): string | null | undefined {\n if (!hasOwn(value, key)) {\n return undefined;\n }\n const raw = value[key];\n if (typeof raw !== \"string\") {\n return null;\n }\n const trimmed = raw.trim();\n return trimmed || null;\n}\n\nfunction readStreamPayload(url: string): NcpStreamRequestPayload | null {\n const sessionId = new URL(url).searchParams.get(\"sessionId\")?.trim();\n return sessionId ? { sessionId } : null;\n}\n\nfunction isAbortPayload(value: unknown): value is NcpMessageAbortPayload {\n return isRecord(value) && typeof value.sessionId === \"string\" && value.sessionId.trim().length > 0;\n}\n\nclass UiRouteRegistry {\n constructor(\n private readonly app: Hono,\n private readonly options: UiRouterOptions,\n private readonly controllers: UiRouteControllers,\n ) {}\n\n private readonly mountRoutes = (routes: readonly RouteDefinition[]): void => {\n for (const [method, path, handler] of routes) {\n this.app[method](path, handler);\n }\n };\n\n private readonly mountAgentRunRoutes = (\n basePath: string,\n kernel: UiRouterOptions[\"kernel\"],\n ): void => {\n this.app.post(`${basePath}/send`, async (c) => {\n const body = await readJson<AgentRunSendIngressPayload>(c.req.raw);\n if (!body.ok || !isValidSendEnvelope(body.data)) {\n return c.json(err(\"INVALID_BODY\", \"Invalid NCP request envelope.\"), 400);\n }\n const handle = await kernel.ingress.handle<AgentRunSendIngressPayload, NcpRunHandle>(\n {\n type: ingressKeys.agentRun.send,\n payload: body.data,\n },\n { source: \"ui-http\" },\n );\n return c.json(ok(handle));\n });\n this.app.get(`${basePath}/stream`, (c) => {\n const payload = readStreamPayload(c.req.raw.url);\n if (!payload) {\n return c.json(err(\"INVALID_QUERY\", \"sessionId is required.\"), 400);\n }\n return createNcpSessionEventStreamResponse(kernel.eventBus, payload, c.req.raw.signal);\n });\n this.app.post(`${basePath}/abort`, async (c) => {\n const body = await readJson<NcpMessageAbortPayload>(c.req.raw);\n if (!body.ok || !isAbortPayload(body.data)) {\n return c.json(err(\"INVALID_BODY\", \"sessionId is required.\"), 400);\n }\n await kernel.ingress.handle<NcpMessageAbortPayload, void>(\n {\n type: ingressKeys.agentRun.abort,\n payload: body.data,\n },\n { source: \"ui-http\" },\n );\n return c.json(ok({ accepted: true }));\n });\n };\n\n private readonly mountNcpAgentRoutes = (\n kernel: UiRouterOptions[\"kernel\"],\n ncpAsset: UiRouteControllers[\"ncpAsset\"],\n ): void => {\n this.mountAgentRunRoutes(NCP_AGENT_BASE_PATH, kernel);\n this.mountRoutes([\n [\"post\", \"/api/ncp/assets\", ncpAsset.putAssets],\n [\"get\", \"/api/ncp/assets/content\", ncpAsset.getAssetContent],\n ]);\n };\n\n private readonly mountResourceRoutes = (): void => {\n const {\n ncpSession,\n panelApps,\n preferences,\n serviceApps,\n serverPath,\n } = this.controllers;\n this.mountRoutes([\n [\"get\", \"/api/ncp/session-types\", ncpSession.getSessionTypes],\n [\"get\", \"/api/ncp/sessions\", ncpSession.listSessions],\n [\"get\", \"/api/ncp/sessions/:sessionId\", ncpSession.getSession],\n [\"put\", \"/api/ncp/sessions/:sessionId\", ncpSession.patchSession],\n [\"get\", \"/api/ncp/sessions/:sessionId/messages\", ncpSession.listSessionMessages],\n [\"get\", \"/api/ncp/sessions/:sessionId/skills\", ncpSession.getSessionSkills],\n [\"delete\", \"/api/ncp/sessions/:sessionId\", ncpSession.deleteSession],\n [\"get\", \"/api/panel-apps\", panelApps.list],\n [\"get\", \"/api/panel-app-bridge.js\", panelApps.getPanelAppBridgeScript],\n [\"get\", \"/api/panel-app-client-sdk.js\", panelApps.getPanelAppClientSdkScript],\n [\"post\", \"/api/panel-app-bridge-sessions\", panelApps.createBridgeSession],\n [\"delete\", \"/api/panel-app-bridge-sessions/:token\", panelApps.deleteBridgeSession],\n [\"post\", \"/api/panel-app-client-grants/:appId\", panelApps.grantClient],\n [\"delete\", \"/api/panel-app-client-grants/:appId\", panelApps.revokeClient],\n [\"post\", \"/api/panel-app-agent/send\", panelApps.sendAgentMessage],\n [\"post\", \"/api/panel-app-agent/generate-object\", panelApps.generateAgentObject],\n [\"post\", \"/api/panel-app-agent-capabilities/:capability/grant\", panelApps.grantAgentCapability],\n [\"patch\", \"/api/panel-apps/:id/preferences\", panelApps.updatePanelAppPreferences],\n [\"get\", \"/api/preferences/:key\", preferences.get],\n [\"put\", \"/api/preferences/:key\", preferences.update],\n [\"delete\", \"/api/preferences/:key\", preferences.delete],\n [\"delete\", \"/api/panel-apps/:id\", panelApps.deletePanelApp],\n [\"post\", \"/api/panel-apps/:id/open\", panelApps.recordPanelAppOpened],\n [\"get\", \"/api/panel-apps/:id/content\", panelApps.getPanelAppContent],\n [\"get\", \"/api/panel-apps/:id/assets/*\", panelApps.getPanelAppAsset],\n [\"get\", \"/api/panel-app-assets/:token/*\", panelApps.getPanelAppAssetByToken],\n [\"get\", \"/api/service-apps\", serviceApps.listServiceApps],\n [\"post\", \"/api/service-apps/:appId/restart\", serviceApps.restartServiceApp],\n [\"post\", \"/api/service-apps/:appId/actions/discover\", serviceApps.discoverServiceAppActions],\n [\"get\", \"/api/service-apps/:appId\", serviceApps.getServiceApp],\n [\"delete\", \"/api/service-apps/:appId\", serviceApps.deleteServiceApp],\n [\"get\", \"/api/service-actions\", serviceApps.listServiceActions],\n [\"post\", \"/api/service-actions/:actionId/invoke\", serviceApps.invokeServiceAction],\n [\"post\", \"/api/service-actions/:actionId/grant\", serviceApps.grantServiceAction],\n [\"delete\", \"/api/service-actions/:actionId/grant\", serviceApps.revokeServiceAction],\n [\"get\", \"/api/service-action-grants\", serviceApps.listServiceActionGrants],\n [\"post\", \"/api/service-action-grants\", serviceApps.grantServiceActions],\n [\"delete\", \"/api/service-action-grants/:actionId\", serviceApps.revokeServiceActionGrant],\n [\"get\", \"/api/server-paths/browse\", serverPath.browse],\n [\"get\", \"/api/server-paths/read\", serverPath.read],\n ]);\n };\n\n readonly register = (): void => {\n const {\n agents,\n app,\n auth,\n config,\n cron,\n ncpAsset,\n remote,\n runtimeControl,\n runtimeUpdate,\n } = this.controllers;\n this.mountRoutes([\n [\"get\", \"/api/health\", app.health],\n [\"get\", \"/api/app/meta\", app.appMeta],\n [\"get\", \"/api/runtime/bootstrap-status\", app.bootstrapStatus],\n [\"get\", \"/api/auth/status\", auth.getStatus],\n [\"post\", \"/api/auth/setup\", auth.setup],\n [\"post\", \"/api/auth/login\", auth.login],\n [\"post\", \"/api/auth/logout\", auth.logout],\n [\"put\", \"/api/auth/password\", auth.updatePassword],\n [\"put\", \"/api/auth/enabled\", auth.updateEnabled],\n [\"post\", \"/api/auth/bridge\", auth.issueBridgeSession],\n [\"get\", \"/api/agents\", agents.listAgents],\n [\"post\", \"/api/agents\", agents.createAgent],\n [\"put\", \"/api/agents/:agentId\", agents.updateAgent],\n [\"delete\", \"/api/agents/:agentId\", agents.deleteAgent],\n [\"get\", \"/api/agents/:agentId/avatar\", agents.getAgentAvatar],\n ]);\n this.mountRoutes([\n [\"get\", \"/api/config\", config.getConfig],\n [\"get\", \"/api/config/meta\", config.getConfigMeta],\n [\"get\", \"/api/config/schema\", config.getConfigSchema],\n [\"get\", \"/api/providers\", config.listProviders],\n [\"get\", \"/api/provider-templates\", config.listProviderTemplates],\n [\"post\", \"/api/providers\", config.createProvider],\n [\"put\", \"/api/providers/:providerId\", config.updateProvider],\n [\"delete\", \"/api/providers/:providerId\", config.deleteProvider],\n [\"post\", \"/api/providers/:providerId/test\", config.testProviderConnection],\n [\"post\", \"/api/providers/:providerId/auth/start\", config.startProviderAuth],\n [\"post\", \"/api/providers/:providerId/auth/poll\", config.pollProviderAuth],\n [\"post\", \"/api/providers/:providerId/auth/import-cli\", config.importProviderAuthFromCli],\n [\"put\", \"/api/config/model\", config.updateConfigModel],\n [\"put\", \"/api/config/search\", config.updateConfigSearch],\n [\"put\", \"/api/config/channels/:channel\", config.updateChannel],\n [\"post\", \"/api/config/channels/:channel/auth/start\", config.startChannelAuth],\n [\"post\", \"/api/config/channels/:channel/auth/connect\", config.connectChannelAuth],\n [\"post\", \"/api/config/channels/:channel/auth/poll\", config.pollChannelAuth],\n [\"put\", \"/api/config/secrets\", config.updateSecrets],\n [\"put\", \"/api/config/runtime\", config.updateRuntime],\n [\"post\", \"/api/config/actions/:actionId/execute\", config.executeAction],\n ]);\n this.mountResourceRoutes();\n this.mountAgentRunRoutes(AGENT_RUNS_BASE_PATH, this.options.kernel);\n this.mountNcpAgentRoutes(this.options.kernel, ncpAsset);\n this.mountRoutes([\n [\"get\", \"/api/cron\", cron.listJobs],\n [\"post\", \"/api/cron\", cron.createJob],\n [\"delete\", \"/api/cron/:id\", cron.deleteJob],\n [\"put\", \"/api/cron/:id/enable\", cron.enableJob],\n [\"post\", \"/api/cron/:id/run\", cron.runJob],\n ]);\n if (remote) {\n this.mountRoutes([\n [\"get\", \"/api/remote/status\", remote.getStatus],\n [\"get\", \"/api/remote/doctor\", remote.getDoctor],\n [\"post\", \"/api/remote/login\", remote.login],\n [\"post\", \"/api/remote/auth/start\", remote.startBrowserAuth],\n [\"post\", \"/api/remote/auth/poll\", remote.pollBrowserAuth],\n [\"post\", \"/api/remote/logout\", remote.logout],\n [\"put\", \"/api/remote/account/profile\", remote.updateProfile],\n [\"put\", \"/api/remote/settings\", remote.updateSettings],\n [\"post\", \"/api/remote/service/:action\", remote.controlService],\n ]);\n }\n if (runtimeControl) {\n this.mountRoutes([\n [\"get\", \"/api/runtime/control\", runtimeControl.getControl],\n [\"post\", \"/api/runtime/control/start-service\", runtimeControl.startService],\n [\"post\", \"/api/runtime/control/restart-service\", runtimeControl.restartService],\n [\"post\", \"/api/runtime/control/stop-service\", runtimeControl.stopService],\n ]);\n }\n if (runtimeUpdate) {\n this.mountRoutes([\n [\"get\", \"/api/runtime/update\", runtimeUpdate.getState],\n [\"post\", \"/api/runtime/update/check\", runtimeUpdate.checkForUpdates],\n [\"post\", \"/api/runtime/update/download\", runtimeUpdate.downloadUpdate],\n [\"post\", \"/api/runtime/update/apply\", runtimeUpdate.applyDownloadedUpdate],\n [\"put\", \"/api/runtime/update/preferences\", runtimeUpdate.updatePreferences],\n [\"put\", \"/api/runtime/update/channel\", runtimeUpdate.updateChannel],\n ]);\n }\n this.app.post(\"/webhook\", async (c) => {\n const ingress = this.options.kernel.ingress;\n const body = await readJson<IngressEnvelope>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid ingress body\"), 400);\n }\n try {\n const result = await ingress.handle(body.data, {\n source: \"webhook\",\n token: /^Bearer\\s+(.+)$/i.exec(c.req.raw.headers.get(\"authorization\")?.trim() ?? \"\")?.[1]?.trim() || null,\n });\n return c.json(ok(result ?? { accepted: true }));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n const status = message.toLowerCase().includes(\"unauthorized\") ? 401 : 400;\n return c.json(err(\"WEBHOOK_FAILED\", message), status);\n }\n });\n mountMarketplaceRoutes(this.app, {\n skill: this.controllers.skillMarketplace,\n mcp: this.controllers.mcpMarketplace\n });\n };\n}\n\nexport function createUiRouter(options: UiRouterOptions, authServiceOverride?: UiAuthService): Hono {\n const app = new Hono();\n const marketplaceBaseUrl = normalizeMarketplaceBaseUrl(options);\n const authService = authServiceOverride ?? options.authService ?? new UiAuthService(\n options.kernel.accessManager ?? new AccessManager({ configPath: options.configPath }),\n );\n const controllers = createUiRouteControllers(options, authService, marketplaceBaseUrl);\n\n app.notFound((c) => c.json(err(\"NOT_FOUND\", \"endpoint not found\"), 404));\n\n app.use(\"/api/*\", async (c, next) => {\n const path = c.req.path;\n if (\n path === \"/api/health\" ||\n path === \"/api/runtime/bootstrap-status\" ||\n path.startsWith(\"/api/auth/\") ||\n path.startsWith(\"/api/panel-app-assets/\")\n ) {\n await next();\n return;\n }\n if (!authService.isProtectionEnabled() || authService.isRequestAuthenticated(c.req.raw)) {\n await next();\n return;\n }\n c.status(401);\n return c.json(err(\"UNAUTHORIZED\", \"Authentication required.\"), 401);\n });\n\n new UiRouteRegistry(app, options, controllers).register();\n\n return app;\n}\n","import { Hono } from \"hono\";\nimport { compress } from \"hono/compress\";\nimport { serve } from \"@hono/node-server\";\nimport { AccessManager } from \"@nextclaw/kernel\";\nimport { WebSocketServer } from \"ws\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { readFile, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { Server } from \"node:http\";\nimport { UiAuthService } from \"@nextclaw-server/features/auth/index.js\";\nimport {\n EventStreamAuthService,\n EventStreamClientRegistry,\n} from \"@nextclaw-server/features/event-stream/index.js\";\nimport { createUiRouter } from \"./router.js\";\nimport type { UiRouterOptions } from \"@nextclaw-server/app/types/router-options.types.js\";\nimport { serveStatic } from \"hono/serve-static\";\n\nexport type UiServerHandle = {\n host: string;\n port: number;\n close: () => Promise<void>;\n};\n\nconst DEFAULT_CORS_ORIGINS = (origin: string | undefined | null) => {\n if (!origin) {\n return undefined;\n }\n if (origin.startsWith(\"http://localhost:\") || origin.startsWith(\"http://127.0.0.1:\")) {\n return origin;\n }\n return undefined;\n};\n\nconst DEFAULT_ALLOWED_CORS_HEADERS = \"Content-Type, Authorization\";\nconst DEFAULT_ALLOWED_CORS_METHODS = \"GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS\";\nconst NULL_ORIGIN = \"null\";\nconst PANEL_APP_RUNTIME_TOKEN_HEADER = \"x-nextclaw-panel-bridge-session\";\nconst STALE_UI_ASSET_RELOAD_MODULE = \"globalThis.location?.reload();\\nexport {};\\n\";\ntype CorsPolicy = string[] | \"*\" | typeof DEFAULT_CORS_ORIGINS;\n\nfunction buildVaryHeader(current: string | null, value: string): string {\n if (!current) {\n return value;\n }\n const values = current\n .split(\",\")\n .map((item) => item.trim())\n .filter(Boolean);\n if (!values.includes(value)) {\n return [...values, value].join(\", \");\n }\n return values.join(\", \");\n}\n\nfunction resolveAllowedCorsOrigin(\n requestOrigin: string | null,\n policy: CorsPolicy\n): string | null {\n if (!requestOrigin) {\n return null;\n }\n if (policy === \"*\") {\n return requestOrigin;\n }\n if (Array.isArray(policy)) {\n return policy.includes(requestOrigin) ? requestOrigin : null;\n }\n return policy(requestOrigin) ?? null;\n}\n\nfunction createCorsHeaders(allowOrigin: string, allowHeaders?: string | null, currentVary?: string | null): Headers {\n const headers = new Headers();\n headers.set(\"Access-Control-Allow-Origin\", allowOrigin);\n headers.set(\"Access-Control-Allow-Credentials\", \"true\");\n headers.set(\"Access-Control-Allow-Methods\", DEFAULT_ALLOWED_CORS_METHODS);\n headers.set(\n \"Access-Control-Allow-Headers\",\n allowHeaders?.trim() || DEFAULT_ALLOWED_CORS_HEADERS\n );\n const varyWithOrigin = buildVaryHeader(currentVary ?? null, \"Origin\");\n headers.set(\"Vary\", buildVaryHeader(varyWithOrigin, \"Access-Control-Request-Headers\"));\n return headers;\n}\n\nfunction readRequestedHeaderNames(value: string | null): string[] {\n return (value ?? \"\")\n .split(\",\")\n .map((header) => header.trim().toLowerCase())\n .filter(Boolean);\n}\n\nfunction isPanelAppPublicBrowserResource(path: string): boolean {\n return path === \"/api/panel-app-client-sdk.js\" ||\n path.startsWith(\"/api/panel-app-assets/\") ||\n (/^\\/api\\/panel-apps\\/[^/]+\\/content$/.test(path));\n}\n\nfunction isPanelAppRuntimePreflight(origin: string | null, allowHeaders: string | null): boolean {\n return origin === NULL_ORIGIN && readRequestedHeaderNames(allowHeaders).includes(PANEL_APP_RUNTIME_TOKEN_HEADER);\n}\n\nfunction isValidPanelAppRuntimeRequest(gateway: UiRouterOptions, request: Request): boolean {\n const token = request.headers.get(PANEL_APP_RUNTIME_TOKEN_HEADER)?.trim();\n if (!token) {\n return false;\n }\n try {\n gateway.kernel.panelAppManager.resolvePanelAppBridgeSession(token);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction mountUiStaticAssets(app: Hono, staticDir: string): void {\n if (!existsSync(join(staticDir, \"index.html\"))) {\n return;\n }\n\n const indexHtml = readFileSync(join(staticDir, \"index.html\"), \"utf-8\");\n app.use(\n \"/*\",\n serveStatic({\n root: staticDir,\n join,\n getContent: async (path) => {\n try {\n return await readFile(path);\n } catch {\n return null;\n }\n },\n isDir: async (path) => {\n try {\n return (await stat(path)).isDirectory();\n } catch {\n return false;\n }\n },\n onFound: (_, c) => {\n c.header(\"cache-control\", \"no-store\");\n }\n })\n );\n app.get(\"/assets/*\", (c) => {\n if (!c.req.path.endsWith(\".js\")) {\n return c.notFound();\n }\n return c.body(STALE_UI_ASSET_RELOAD_MODULE, 200, {\n \"content-type\": \"application/javascript; charset=utf-8\",\n \"cache-control\": \"no-store\"\n });\n });\n app.get(\"*\", (c) => {\n const path = c.req.path;\n if (path.startsWith(\"/api\") || path.startsWith(\"/ws\") || path.startsWith(\"/_remote\") || path.startsWith(\"/webhook\")) {\n return c.notFound();\n }\n return c.html(indexHtml, 200, { \"cache-control\": \"no-store\" });\n });\n}\n\nfunction attachUiSocketServer(\n httpServer: Server,\n eventStreamAuth: EventStreamAuthService,\n eventStreamClients: EventStreamClientRegistry,\n): WebSocketServer {\n const wss = new WebSocketServer({ noServer: true });\n httpServer.on(\"upgrade\", (request, socket, head) => {\n const host = request.headers.host ?? \"127.0.0.1\";\n const url = request.url ?? \"/\";\n const pathname = new URL(url, `http://${host}`).pathname;\n if (pathname !== \"/ws\") {\n return;\n }\n const principal = eventStreamAuth.authenticate(request);\n if (!principal) {\n socket.write(\"HTTP/1.1 401 Unauthorized\\r\\nConnection: close\\r\\n\\r\\n\");\n socket.destroy();\n return;\n }\n wss.handleUpgrade(request, socket, head, (ws) => {\n eventStreamClients.add(ws, principal);\n wss.emit(\"connection\", ws, request);\n });\n });\n return wss;\n}\n\nexport async function startUiServer(gateway: UiRouterOptions): Promise<UiServerHandle> {\n const {\n corsOrigins,\n uiStaticDir,\n } = gateway;\n const uiConfig = gateway.uiConfig;\n if (!uiConfig) {\n throw new Error(\"uiConfig is required to start UI server\");\n }\n const { host, port } = uiConfig;\n const app = new Hono();\n app.use(\"/*\", compress());\n const corsPolicy = corsOrigins ?? DEFAULT_CORS_ORIGINS;\n const authService = new UiAuthService(\n gateway.kernel.accessManager ?? new AccessManager({ configPath: gateway.configPath }),\n );\n app.use(\"/api/*\", async (c, next) => {\n const origin = c.req.header(\"origin\")?.trim() ?? null;\n const path = c.req.path;\n const allowOrigin = resolveAllowedCorsOrigin(origin, corsPolicy);\n const allowHeaders = c.req.header(\"access-control-request-headers\")?.trim() ?? null;\n const isPanelAppRuntimeCors = isPanelAppRuntimePreflight(origin, allowHeaders) ||\n (origin === NULL_ORIGIN && isValidPanelAppRuntimeRequest(gateway, c.req.raw));\n\n if (c.req.method === \"OPTIONS\") {\n if (allowOrigin) {\n const headers = createCorsHeaders(allowOrigin, allowHeaders);\n return new Response(null, { status: 204, headers });\n }\n if (isPanelAppRuntimePreflight(origin, allowHeaders)) {\n const headers = createCorsHeaders(NULL_ORIGIN, allowHeaders);\n return new Response(null, { status: 204, headers });\n }\n return new Response(null, { status: 204 });\n }\n\n if (\n origin === NULL_ORIGIN &&\n !allowOrigin &&\n !isPanelAppRuntimeCors &&\n !isPanelAppPublicBrowserResource(path)\n ) {\n return new Response(\"Panel App runtime token is required.\", {\n status: 401,\n headers: { \"content-type\": \"text/plain; charset=utf-8\" },\n });\n }\n\n await next();\n\n const resolvedAllowOrigin = allowOrigin ?? (isPanelAppRuntimeCors ? NULL_ORIGIN : null);\n if (resolvedAllowOrigin) {\n for (const [name, value] of createCorsHeaders(resolvedAllowOrigin, allowHeaders, c.res.headers.get(\"Vary\"))) {\n c.res.headers.set(name, value);\n }\n }\n });\n\n const eventStreamAuth = new EventStreamAuthService({\n uiAuth: authService,\n extensionAuth: gateway.extensions,\n getChannelBindings: gateway.extensions?.getChannelBindings,\n });\n const eventStreamClients = new EventStreamClientRegistry();\n const unsubscribeEventBus = gateway.appEventBus.subscribeAll(eventStreamClients.publish);\n\n app.route(\n \"/\",\n createUiRouter(gateway, authService)\n );\n\n if (uiStaticDir) {\n mountUiStaticAssets(app, uiStaticDir);\n }\n\n const server = await new Promise<Server>((resolve, reject) => {\n const httpServer = serve(\n {\n fetch: app.fetch,\n port,\n hostname: host\n },\n () => resolve(httpServer as unknown as Server)\n ) as unknown as Server;\n httpServer.once(\"error\", reject);\n });\n\n const httpServer = server as unknown as Server;\n const wss = attachUiSocketServer(httpServer, eventStreamAuth, eventStreamClients);\n\n return {\n host,\n port,\n close: () =>\n new Promise((resolve) => {\n unsubscribeEventBus();\n eventStreamClients.closeAll();\n wss.close(() => {\n server.close(() => resolve());\n });\n })\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["isRecord","normalizeOptionalString","MASK_MIN_LENGTH","normalizeOptionalString","maskApiKey","clearSecretRef","isRecord","PANEL_BRIDGE_SESSION_HEADER","isRecord","isRecord","isRecord"],"sources":["../src/features/auth/utils/auth-bridge.utils.ts","../src/shared/utils/http-response.utils.ts","../src/features/auth/controllers/auth.controller.ts","../src/features/auth/utils/access-cookie.utils.ts","../src/features/auth/services/ui-auth.service.ts","../src/features/event-stream/services/event-stream-auth.service.ts","../src/features/event-stream/utils/event-stream-authorizer.utils.ts","../src/features/event-stream/services/event-stream-client-registry.service.ts","../../nextclaw-shared/src/types/typed-key.types.ts","../../nextclaw-shared/src/configs/event-keys.config.ts","../../nextclaw-shared/src/configs/ingress-keys.config.ts","../src/features/agents/stores/agents.store.ts","../src/shared/utils/app-events.utils.ts","../src/features/agents/controllers/agents.controller.ts","../src/app/controllers/app.controller.ts","../src/features/config/utils/extension-channel-config-projection.utils.ts","../src/features/config/utils/channel-auth.utils.ts","../src/features/config/providers/server-builtin-provider.provider.ts","../src/features/config/utils/provider-auth.utils.ts","../src/features/config/controllers/config.controller.ts","../src/features/config/utils/default-provider-config.utils.ts","../src/features/config/utils/runtime-entry-config.utils.ts","../src/features/config/utils/search-config.utils.ts","../src/features/config/stores/server-config.store.ts","../src/features/cron/controllers/cron.controller.ts","../src/features/attachments/controllers/attachments.controller.ts","../src/features/sessions/utils/session-preference-patch.utils.ts","../src/features/sessions/utils/session-project-root.utils.ts","../src/features/marketplace/configs/marketplace.constants.config.ts","../src/features/marketplace/utils/marketplace-network-retry.utils.ts","../src/features/marketplace/utils/marketplace-catalog.utils.ts","../src/features/marketplace/controllers/mcp-marketplace.controller.ts","../src/features/marketplace/utils/marketplace-installed.utils.ts","../src/features/marketplace/controllers/skill-marketplace.controller.ts","../src/features/marketplace/routes/marketplace.route.ts","../src/features/sessions/services/session-skills-view.service.ts","../src/features/sessions/controllers/sessions.controller.ts","../src/features/remote-access/controllers/remote.controller.ts","../src/features/runtime-control/controllers/runtime-control.controller.ts","../src/features/runtime-update/controllers/runtime-update.controller.ts","../src/features/panel-apps/controllers/panel-apps.controller.ts","../src/features/preferences/controllers/preferences.controller.ts","../src/features/service-apps/controllers/service-apps.controller.ts","../src/app/utils/ncp-session-event-stream.utils.ts","../src/features/server-path/utils/server-path-browse.utils.ts","../src/features/server-path/utils/server-path-read.utils.ts","../src/features/server-path/controllers/server-path.controller.ts","../src/app/router.ts","../src/app/server.ts"],"sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { randomBytes } from \"node:crypto\";\nimport { getDataDir } from \"@nextclaw/core\";\n\nconst REMOTE_BRIDGE_DIR = join(getDataDir(), \"remote\");\nconst REMOTE_BRIDGE_SECRET_PATH = join(REMOTE_BRIDGE_DIR, \"ui-bridge-secret\");\n\nexport function getUiBridgeSecretPath(): string {\n return REMOTE_BRIDGE_SECRET_PATH;\n}\n\nexport function readUiBridgeSecret(): string | null {\n if (!existsSync(REMOTE_BRIDGE_SECRET_PATH)) {\n return null;\n }\n try {\n const raw = readFileSync(REMOTE_BRIDGE_SECRET_PATH, \"utf-8\").trim();\n return raw.length > 0 ? raw : null;\n } catch {\n return null;\n }\n}\n\nexport function ensureUiBridgeSecret(): string {\n const existing = readUiBridgeSecret();\n if (existing) {\n return existing;\n }\n mkdirSync(REMOTE_BRIDGE_DIR, { recursive: true });\n const secret = randomBytes(24).toString(\"hex\");\n writeFileSync(REMOTE_BRIDGE_SECRET_PATH, `${secret}\\n`, \"utf-8\");\n return secret;\n}\n","export function ok<T>(data: T) {\n return { ok: true, data };\n}\n\nexport function err(code: string, message: string, details?: Record<string, unknown>) {\n return { ok: false, error: { code, message, details } };\n}\n\nexport async function readJson<T>(req: Request): Promise<{ ok: true; data: T } | { ok: false }> {\n try {\n const data = (await req.json()) as T;\n return { ok: true, data };\n } catch {\n return { ok: false };\n }\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nexport function readErrorMessage(value: unknown, fallback: string): string {\n if (!isRecord(value)) {\n return fallback;\n }\n\n const maybeError = value.error;\n if (!isRecord(maybeError)) {\n return fallback;\n }\n\n return typeof maybeError.message === \"string\" && maybeError.message.trim().length > 0\n ? maybeError.message\n : fallback;\n}\n\nexport function readNonEmptyString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed || undefined;\n}\n\nexport function formatUserFacingError(error: unknown, maxChars = 320): string {\n const raw =\n error instanceof Error ? error.message || error.name || \"Unknown error\" : String(error ?? \"Unknown error\");\n const normalized = raw.replace(/\\s+/g, \" \").trim();\n if (!normalized) {\n return \"Unknown error\";\n }\n if (normalized.length <= maxChars) {\n return normalized;\n }\n return `${normalized.slice(0, Math.max(0, maxChars - 3)).trimEnd()}...`;\n}\n","import type { Context } from \"hono\";\nimport type { UiAuthService } from \"@nextclaw-server/features/auth/index.js\";\nimport { ensureUiBridgeSecret } from \"@nextclaw-server/features/auth/utils/auth-bridge.utils.js\";\nimport type {\n AuthEnabledUpdateRequest,\n AuthLoginRequest,\n AuthPasswordUpdateRequest,\n AuthSetupRequest\n} from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport { err, ok, readJson } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\n\nfunction isAuthenticationRequiredError(message: string): boolean {\n return message === \"Authentication required.\";\n}\n\nfunction isConflictError(message: string): boolean {\n return message.includes(\"already configured\");\n}\n\nfunction setCookieHeader(c: Context, cookie: string | undefined): void {\n if (!cookie) {\n return;\n }\n c.header(\"Set-Cookie\", cookie);\n}\n\nexport class AuthRoutesController {\n constructor(private readonly authService: UiAuthService) {}\n\n readonly getStatus = (c: Context) => {\n return c.json(ok(this.authService.getStatus(c.req.raw)));\n };\n\n readonly setup = async (c: Context) => {\n const body = await readJson<AuthSetupRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n if (typeof body.data.username !== \"string\" || typeof body.data.password !== \"string\") {\n return c.json(err(\"INVALID_BODY\", \"username and password are required\"), 400);\n }\n\n try {\n const result = await this.authService.setup(c.req.raw, body.data);\n setCookieHeader(c, result.cookie);\n return c.json(ok(result.status), 201);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return c.json(err(isConflictError(message) ? \"AUTH_ALREADY_CONFIGURED\" : \"INVALID_BODY\", message), isConflictError(message) ? 409 : 400);\n }\n };\n\n readonly login = async (c: Context) => {\n const body = await readJson<AuthLoginRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n if (typeof body.data.username !== \"string\" || typeof body.data.password !== \"string\") {\n return c.json(err(\"INVALID_BODY\", \"username and password are required\"), 400);\n }\n\n try {\n const result = this.authService.login(c.req.raw, body.data);\n setCookieHeader(c, result.cookie);\n return c.json(ok(result.status));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n const code = message === \"Invalid username or password.\" ? \"INVALID_CREDENTIALS\" : \"AUTH_NOT_ENABLED\";\n const status = message === \"Invalid username or password.\" ? 401 : 400;\n return c.json(err(code, message), status);\n }\n };\n\n readonly logout = (c: Context) => {\n this.authService.logout(c.req.raw);\n setCookieHeader(c, this.authService.buildLogoutCookie(c.req.raw));\n return c.json(ok({ success: true }));\n };\n\n readonly updatePassword = async (c: Context) => {\n const body = await readJson<AuthPasswordUpdateRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n if (typeof body.data.password !== \"string\") {\n return c.json(err(\"INVALID_BODY\", \"password is required\"), 400);\n }\n\n try {\n const result = await this.authService.updatePassword(c.req.raw, body.data);\n setCookieHeader(c, result.cookie);\n return c.json(ok(result.status));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n const status = isAuthenticationRequiredError(message) ? 401 : 400;\n const code = isAuthenticationRequiredError(message) ? \"UNAUTHORIZED\" : \"INVALID_BODY\";\n return c.json(err(code, message), status);\n }\n };\n\n readonly updateEnabled = async (c: Context) => {\n const body = await readJson<AuthEnabledUpdateRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n if (typeof body.data.enabled !== \"boolean\") {\n return c.json(err(\"INVALID_BODY\", \"enabled is required\"), 400);\n }\n\n try {\n const result = await this.authService.updateEnabled(c.req.raw, body.data);\n setCookieHeader(c, result.cookie);\n return c.json(ok(result.status));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n const status = isAuthenticationRequiredError(message) ? 401 : 400;\n const code = isAuthenticationRequiredError(message) ? \"UNAUTHORIZED\" : \"INVALID_BODY\";\n return c.json(err(code, message), status);\n }\n };\n\n readonly issueBridgeSession = (c: Context) => {\n const providedSecret = c.req.header(\"x-nextclaw-ui-bridge-secret\")?.trim();\n const expectedSecret = ensureUiBridgeSecret();\n if (!providedSecret || providedSecret !== expectedSecret) {\n return c.json(err(\"FORBIDDEN\", \"Invalid bridge secret.\"), 403);\n }\n return c.json(ok({\n cookie: this.authService.buildTrustedRequestCookieHeader()\n }));\n };\n}\n","const SESSION_COOKIE_NAME = \"nextclaw_ui_session\";\n\nexport function readAccessSessionTokenFromCookieHeader(rawHeader: string | null | undefined): string | null {\n if (!rawHeader) {\n return null;\n }\n for (const chunk of rawHeader.split(\";\")) {\n const [rawKey, ...rawValue] = chunk.split(\"=\");\n const key = rawKey?.trim();\n if (key === SESSION_COOKIE_NAME) {\n const value = decodeURIComponent(rawValue.join(\"=\").trim());\n return value.trim() ? value.trim() : null;\n }\n }\n return null;\n}\n\nexport function buildAccessLoginCookie(params: {\n token: string;\n secure: boolean;\n expiresAt?: string;\n}): string {\n const { expiresAt, secure, token } = params;\n const parts = [\n `${SESSION_COOKIE_NAME}=${encodeURIComponent(token)}`,\n \"Path=/\",\n \"HttpOnly\",\n \"SameSite=Lax\",\n ];\n if (secure) {\n parts.push(\"Secure\");\n }\n if (expiresAt) {\n const expiresAtMs = Date.parse(expiresAt);\n if (Number.isFinite(expiresAtMs)) {\n const maxAgeSeconds = Math.max(0, Math.trunc((expiresAtMs - Date.now()) / 1000));\n parts.push(`Max-Age=${maxAgeSeconds}`);\n parts.push(`Expires=${new Date(expiresAtMs).toUTCString()}`);\n }\n }\n return parts.join(\"; \");\n}\n\nexport function buildAccessLogoutCookie(secure: boolean): string {\n return [\n `${SESSION_COOKIE_NAME}=`,\n \"Path=/\",\n \"HttpOnly\",\n \"SameSite=Lax\",\n secure ? \"Secure\" : null,\n \"Max-Age=0\",\n `Expires=${new Date(0).toUTCString()}`,\n ].filter((part): part is string => part !== null).join(\"; \");\n}\n\nexport function resolveSecureRequest(url: string, protocolHint?: string | null): boolean {\n if (protocolHint?.trim().toLowerCase() === \"https\") {\n return true;\n }\n try {\n return new URL(url).protocol === \"https:\";\n } catch {\n return false;\n }\n}\n\n","import type { IncomingMessage } from \"node:http\";\nimport type { AccessManager, AccessLoginResult } from \"@nextclaw/kernel\";\nimport type {\n AuthEnabledUpdateRequest,\n AuthLoginRequest,\n AuthPasswordUpdateRequest,\n AuthSetupRequest,\n AuthStatusView,\n} from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport {\n buildAccessLoginCookie,\n buildAccessLogoutCookie,\n readAccessSessionTokenFromCookieHeader,\n resolveSecureRequest,\n} from \"@nextclaw-server/features/auth/utils/access-cookie.utils.js\";\n\nexport class UiAuthService {\n constructor(private readonly accessManager: AccessManager) {}\n\n isProtectionEnabled = (): boolean => this.accessManager.isPasswordProtectionEnabled();\n\n isRequestAuthenticated = (request: Request): boolean => {\n if (!this.isProtectionEnabled()) {\n return true;\n }\n return this.accessManager.authenticateSession(this.readRequestToken(request)) !== null;\n };\n\n isSocketAuthenticated = (request: IncomingMessage): boolean => {\n if (!this.isProtectionEnabled()) {\n return true;\n }\n const rawCookieHeader = Array.isArray(request.headers.cookie)\n ? request.headers.cookie.join(\"; \")\n : request.headers.cookie;\n return this.accessManager.authenticateSession(readAccessSessionTokenFromCookieHeader(rawCookieHeader)) !== null;\n };\n\n getStatus = (request: Request): AuthStatusView => {\n return this.accessManager.getPasswordAuthStatus(this.readRequestToken(request));\n };\n\n setup = async (request: Request, payload: AuthSetupRequest): Promise<{ status: AuthStatusView; cookie: string }> => {\n return this.toCookieResult(request, await this.accessManager.setupPasswordAdmin(payload));\n };\n\n login = (request: Request, payload: AuthLoginRequest): { status: AuthStatusView; cookie: string } => {\n return this.toCookieResult(request, this.accessManager.loginWithPassword(payload));\n };\n\n logout = (request: Request): void => {\n this.accessManager.logout(this.readRequestToken(request));\n };\n\n updatePassword = async (\n request: Request,\n payload: AuthPasswordUpdateRequest,\n ): Promise<{ status: AuthStatusView; cookie?: string }> => {\n return this.toOptionalCookieResult(\n request,\n await this.accessManager.updatePassword({\n token: this.readRequestToken(request),\n password: payload.password,\n }),\n );\n };\n\n updateEnabled = async (\n request: Request,\n payload: AuthEnabledUpdateRequest,\n ): Promise<{ status: AuthStatusView; cookie?: string }> => {\n const result = await this.accessManager.setPasswordAuthEnabled({\n token: this.readRequestToken(request),\n enabled: payload.enabled,\n });\n if (!payload.enabled) {\n return {\n status: result.status,\n cookie: this.buildLogoutCookie(request),\n };\n }\n return this.toOptionalCookieResult(request, result);\n };\n\n buildTrustedRequestCookieHeader = (): string | null => {\n const result = this.accessManager.createTrustedSession();\n return result?.token ? `nextclaw_ui_session=${encodeURIComponent(result.token)}` : null;\n };\n\n buildLogoutCookie = (request: Request): string => {\n return buildAccessLogoutCookie(this.isSecureRequest(request));\n };\n\n private readRequestToken = (request: Request): string | null => {\n return readAccessSessionTokenFromCookieHeader(request.headers.get(\"cookie\"));\n };\n\n private toCookieResult = (\n request: Request,\n result: AccessLoginResult,\n ): { status: AuthStatusView; cookie: string } => {\n if (!result.token) {\n throw new Error(\"Access session token was not created.\");\n }\n return {\n status: result.status,\n cookie: buildAccessLoginCookie({\n token: result.token,\n secure: this.isSecureRequest(request),\n expiresAt: result.expiresAt,\n }),\n };\n };\n\n private toOptionalCookieResult = (\n request: Request,\n result: AccessLoginResult,\n ): { status: AuthStatusView; cookie?: string } => {\n if (!result.token) {\n return {\n status: result.status,\n };\n }\n return this.toCookieResult(request, result);\n };\n\n private isSecureRequest = (request: Request): boolean => {\n return resolveSecureRequest(request.url, request.headers.get(\"x-forwarded-proto\"));\n };\n}\n\n","import type { IncomingMessage } from \"node:http\";\nimport type { ExtensionChannelBinding } from \"@nextclaw/core\";\nimport type { UiAuthService } from \"@nextclaw-server/features/auth/index.js\";\nimport type {\n ExtensionEventStreamAuthenticator,\n EventStreamPrincipal,\n} from \"@nextclaw-server/features/event-stream/types/event-stream-principal.types.js\";\n\nexport type EventStreamAuthServiceDeps = {\n uiAuth: UiAuthService;\n extensionAuth?: ExtensionEventStreamAuthenticator;\n getChannelBindings?: () => ExtensionChannelBinding[];\n};\n\nfunction readHeaderValue(value: string | string[] | undefined): string | null {\n const raw = Array.isArray(value) ? value[0] : value;\n return typeof raw === \"string\" && raw.trim() ? raw.trim() : null;\n}\n\nfunction readBearerToken(value: string | null): string | null {\n if (!value) {\n return null;\n }\n const match = /^Bearer\\s+(.+)$/iu.exec(value);\n return match?.[1]?.trim() || null;\n}\n\nexport class EventStreamAuthService {\n constructor(private readonly deps: EventStreamAuthServiceDeps) {}\n\n authenticate = (request: IncomingMessage): EventStreamPrincipal | null =>\n this.authenticateExtension(request) ?? this.authenticateUi(request);\n\n private readonly authenticateExtension = (request: IncomingMessage): EventStreamPrincipal | null => {\n const token = readBearerToken(readHeaderValue(request.headers.authorization));\n const extensionId = readHeaderValue(request.headers[\"x-nextclaw-extension-id\"]);\n const result = this.deps.extensionAuth?.authenticateEventStreamCredential({\n extensionId,\n token,\n });\n if (!result) {\n return null;\n }\n return {\n principalId: `extension:${result.extensionId}`,\n grants: [\n \"event-stream:extension-requests\",\n \"event-stream:ncp-events\",\n \"event-stream:config-events\",\n ],\n scopes: {\n extensionIds: [result.extensionId],\n channelIds: this.getExtensionChannelIds(result.extensionId),\n },\n };\n };\n\n private readonly authenticateUi = (request: IncomingMessage): EventStreamPrincipal | null => {\n if (!this.deps.uiAuth.isSocketAuthenticated(request)) {\n return null;\n }\n return {\n principalId: \"ui\",\n grants: [\"event-stream:ui-events\"],\n scopes: {},\n };\n };\n\n private readonly getExtensionChannelIds = (extensionId: string): string[] =>\n this.deps.getChannelBindings?.()\n .filter((binding) => binding.extensionId === extensionId)\n .map((binding) => binding.channelId)\n .filter((channelId) => channelId.trim().length > 0) ?? [];\n}\n","import type { AppEventEnvelope } from \"@nextclaw/shared\";\nimport type {\n EventStreamGrant,\n EventStreamPrincipal,\n} from \"@nextclaw-server/features/event-stream/types/event-stream-principal.types.js\";\n\nfunction readRecord(value: unknown): Record<string, unknown> {\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? value as Record<string, unknown>\n : {};\n}\n\nfunction readString(value: unknown): string | null {\n return typeof value === \"string\" && value.trim() ? value.trim() : null;\n}\n\nfunction hasGrant(principal: EventStreamPrincipal, grant: EventStreamGrant): boolean {\n return principal.grants.includes(grant);\n}\n\nfunction scopeValues(principal: EventStreamPrincipal, key: string): string[] {\n const value = principal.scopes[key];\n if (Array.isArray(value)) {\n return value;\n }\n return value ? [value] : [];\n}\n\nfunction hasScopeValue(principal: EventStreamPrincipal, key: string, value: string | null): boolean {\n return Boolean(value && scopeValues(principal, key).includes(value));\n}\n\nfunction readExtensionRequestTarget(event: AppEventEnvelope): string | null {\n return readString(readRecord(event.payload).extensionId);\n}\n\nfunction parseAgentSessionChannel(sessionId: string | null): string | null {\n if (!sessionId) {\n return null;\n }\n const parts = sessionId.split(\":\");\n return parts[0] === \"agent\" && parts.length >= 5 ? readString(parts[2]) : null;\n}\n\nfunction readNcpEventChannel(event: AppEventEnvelope): string | null {\n const payload = readRecord(event.payload);\n const endpointPayload = readRecord(payload.payload);\n const message = readRecord(payload.message ?? endpointPayload.message);\n const metadata = readRecord(message.metadata ?? payload.metadata);\n return (\n readString(metadata.channelId) ??\n readString(metadata.channel) ??\n parseAgentSessionChannel(readString(message.sessionId) ?? readString(payload.sessionId))\n );\n}\n\nexport function canStreamAppEventToPrincipal(\n principal: EventStreamPrincipal,\n event: AppEventEnvelope,\n): boolean {\n if (event.type === \"extension.request\") {\n return hasGrant(principal, \"event-stream:extension-requests\") &&\n hasScopeValue(principal, \"extensionIds\", readExtensionRequestTarget(event));\n }\n\n if (event.type === \"ncp.event\") {\n if (hasGrant(principal, \"event-stream:ui-events\")) {\n return true;\n }\n return hasGrant(principal, \"event-stream:ncp-events\") &&\n hasScopeValue(principal, \"channelIds\", readNcpEventChannel(event));\n }\n\n if (event.type === \"config.updated\") {\n if (hasGrant(principal, \"event-stream:ui-events\")) {\n return true;\n }\n const path = readString(readRecord(event.payload).path);\n const channelId = path?.startsWith(\"channels.\")\n ? path.slice(\"channels.\".length).trim()\n : null;\n return hasGrant(principal, \"event-stream:config-events\") &&\n (path === \"channels\" || hasScopeValue(principal, \"channelIds\", channelId));\n }\n\n return hasGrant(principal, \"event-stream:ui-events\");\n}\n","import type { AppEventEnvelope } from \"@nextclaw/shared\";\nimport { WebSocket } from \"ws\";\nimport type { EventStreamPrincipal } from \"@nextclaw-server/features/event-stream/types/event-stream-principal.types.js\";\nimport { canStreamAppEventToPrincipal } from \"@nextclaw-server/features/event-stream/utils/event-stream-authorizer.utils.js\";\n\ntype EventStreamClient = {\n socket: WebSocket;\n principal: EventStreamPrincipal;\n};\n\nexport class EventStreamClientRegistry {\n private readonly clients = new Set<EventStreamClient>();\n\n add = (socket: WebSocket, principal: EventStreamPrincipal): void => {\n const client = { socket, principal };\n this.clients.add(client);\n socket.on(\"close\", () => this.clients.delete(client));\n };\n\n publish = (event: AppEventEnvelope): void => {\n const payload = JSON.stringify(event);\n for (const client of this.clients) {\n if (\n client.socket.readyState === WebSocket.OPEN &&\n canStreamAppEventToPrincipal(client.principal, event)\n ) {\n client.socket.send(payload);\n }\n }\n };\n\n closeAll = (): void => {\n for (const client of this.clients) {\n client.socket.close();\n }\n this.clients.clear();\n };\n}\n","export type TypedKey<T = unknown> = {\n readonly id: string;\n readonly _type?: T;\n};\n\nexport type Key<T = unknown> = TypedKey<T> | string;\n\nexport function createTypedKey<T>(id: string): TypedKey<T> {\n const normalizedId = id.trim();\n if (!normalizedId) {\n throw new Error(\"typed key id is required\");\n }\n return { id: normalizedId };\n}\n\nexport function getKeyId(key: Key<unknown>): string {\n return typeof key === \"string\" ? key.trim() : key.id;\n}\n","import type { NcpEndpointEvent, NcpSessionSummary } from \"@nextclaw/ncp\";\nimport type { AppEventKey, EventKey } from \"../types/event-bus.types.js\";\nimport { createTypedKey } from \"../types/typed-key.types.js\";\nimport type { UiShowContentEventPayload } from \"../types/ui-show-content.types.js\";\nimport type { UpdateSnapshot } from \"../types/update.types.js\";\n\nexport function createEventKey<T>(id: string): EventKey<T> {\n return createTypedKey<T>(id);\n}\n\nexport function createAppEventKey<T>(id: string): AppEventKey<T> {\n return createTypedKey<T>(id);\n}\n\nexport const eventKeys = {\n configUpdated: createAppEventKey<{ path: string }>(\"config.updated\"),\n channelConfigApplyStatus: createAppEventKey<{\n channel: string;\n status: \"started\" | \"succeeded\" | \"failed\";\n message?: string;\n }>(\"channel.config.apply-status\"),\n sessionUpdated: createAppEventKey<{ sessionKey: string }>(\"session.updated\"),\n sessionRunStatus: createAppEventKey<{\n sessionKey: string;\n status: \"running\" | \"idle\";\n }>(\"session.run-status\"),\n sessionMetadataChanged: createAppEventKey<{\n metadata: Record<string, unknown>;\n mode: \"set\" | \"update\";\n sessionKey: string;\n }>(\"session.metadata.changed\"),\n ncpEvent: createAppEventKey<NcpEndpointEvent>(\"ncp.event\"),\n sessionSummaryUpsert: createAppEventKey<{ summary: NcpSessionSummary }>(\n \"session.summary.upsert\",\n ),\n sessionSummaryDelete: createAppEventKey<{ sessionKey: string }>(\n \"session.summary.delete\",\n ),\n uiShowContent: createAppEventKey<UiShowContentEventPayload>(\"ui.show-content\"),\n configReloadStarted: createAppEventKey<Record<string, unknown> | undefined>(\n \"config.reload.started\",\n ),\n configReloadFinished: createAppEventKey<Record<string, unknown> | undefined>(\n \"config.reload.finished\",\n ),\n error: createAppEventKey<{ message: string; code?: string }>(\"error\"),\n connectionOpen: createAppEventKey<Record<string, never> | undefined>(\n \"connection.open\",\n ),\n connectionClose: createAppEventKey<Record<string, never> | undefined>(\n \"connection.close\",\n ),\n connectionError: createAppEventKey<{ message?: string } | undefined>(\n \"connection.error\",\n ),\n runtimeUpdateSnapshot: createAppEventKey<UpdateSnapshot>(\n \"runtime.update.snapshot\",\n ),\n} as const;\n","import type {\n NcpAgentSendEnvelope,\n NcpMessage,\n NcpMessageAbortPayload,\n NcpMessagePart,\n} from \"@nextclaw/ncp\";\nimport { createTypedKey } from \"../types/typed-key.types.js\";\n\nexport type ExtensionChannelTextContent = {\n type: \"text\";\n text: string;\n};\n\ntype ExtensionChannelResourceRef = {\n url?: string;\n assetUri?: string;\n mimeType?: string;\n name?: string;\n};\n\nexport type ExtensionChannelImageContent = ExtensionChannelResourceRef & { type: \"image\" };\n\nexport type ExtensionChannelFileContent = ExtensionChannelResourceRef & { type: \"file\" };\n\nexport type ExtensionChannelMessageContent =\n | ExtensionChannelTextContent\n | ExtensionChannelImageContent\n | ExtensionChannelFileContent;\n\nexport type ExtensionChannelSubmittedAttachment = ExtensionChannelResourceRef & {\n id?: string;\n path?: string;\n size?: number;\n source?: string;\n status?: \"ready\" | \"remote-only\";\n errorCode?: \"too_large\" | \"download_failed\" | \"http_error\" | \"invalid_payload\";\n};\n\nexport type ExtensionChannelConfigGetIngressPayload = {\n channelId: string;\n};\n\nexport type ExtensionChannelMessageSubmitIngressPayload = {\n channelId: string;\n conversationId: string;\n senderId: string;\n content: ExtensionChannelMessageContent;\n attachments?: ExtensionChannelSubmittedAttachment[];\n metadata?: Record<string, unknown>;\n};\n\nexport type ExtensionChannelCommandOptionType = \"string\" | \"boolean\" | \"number\";\n\nexport type ExtensionChannelCommandOption = {\n name: string;\n description: string;\n type: ExtensionChannelCommandOptionType;\n required?: boolean;\n};\n\nexport type ExtensionChannelCommandSpec = {\n name: string;\n description: string;\n options?: ExtensionChannelCommandOption[];\n};\n\nexport type ExtensionChannelCommandListIngressPayload = {\n channelId: string;\n};\n\nexport type ExtensionChannelCommandListResponse = {\n commands: ExtensionChannelCommandSpec[];\n};\n\nexport type ExtensionChannelCommandExecuteIngressPayload = {\n channelId: string;\n conversationId: string;\n senderId: string;\n commandName?: string;\n rawText?: string;\n args?: Record<string, unknown>;\n metadata?: Record<string, unknown>;\n};\n\nexport type ExtensionChannelCommandExecuteResponse = {\n content: string;\n ephemeral?: boolean;\n};\n\nexport type ExtensionResponseIngressPayload =\n | {\n requestId: string;\n ok: true;\n data?: unknown;\n }\n | {\n requestId: string;\n ok: false;\n error: {\n message: string;\n };\n };\n\nexport type AgentRunSessionMessageRequestPayload = {\n message: NcpMessage;\n requestId: string;\n sessionId: string;\n};\n\nexport const CHAT_SESSION_MATERIALIZATION_METADATA_KEY = \"session_materialization\";\n\nexport type AgentRunSessionMaterializationMetadata = {\n kind: \"child\";\n parentSessionId: string;\n inheritContext: true;\n};\n\nexport type AgentRunSendIngressMetadata = Record<string, unknown> & {\n agentRuntimeId?: string;\n agentId?: string;\n projectRoot?: string;\n channel?: string;\n model?: string;\n maxTokens?: number;\n thinkingEffort?: string | null;\n chatId?: string;\n accountId?: string;\n senderId?: string;\n sessionKey?: string;\n label?: string;\n [CHAT_SESSION_MATERIALIZATION_METADATA_KEY]?: AgentRunSessionMaterializationMetadata;\n};\n\nexport type AgentRunSendIngressPayload =\n | (Omit<NcpAgentSendEnvelope, \"metadata\"> & {\n content?: never;\n metadata?: AgentRunSendIngressMetadata;\n peerId?: string;\n })\n | (Omit<NcpAgentSendEnvelope, \"message\" | \"metadata\"> & {\n content: NcpMessagePart[];\n metadata?: AgentRunSendIngressMetadata;\n message?: never;\n peerId?: string;\n });\n\nexport const ingressKeys = {\n extension: {\n channelConfigGet: createTypedKey<ExtensionChannelConfigGetIngressPayload>(\n \"extension.channel.config.get\",\n ),\n channelMessageSubmit:\n createTypedKey<ExtensionChannelMessageSubmitIngressPayload>(\n \"extension.channel.message.submit\",\n ),\n channelCommandList: createTypedKey<ExtensionChannelCommandListIngressPayload>(\n \"extension.channel.command.list\",\n ),\n channelCommandExecute:\n createTypedKey<ExtensionChannelCommandExecuteIngressPayload>(\n \"extension.channel.command.execute\",\n ),\n response: createTypedKey<ExtensionResponseIngressPayload>(\"extension.response\"),\n },\n agentRun: {\n send: createTypedKey<AgentRunSendIngressPayload>(\"agent-run.send\"),\n abort: createTypedKey<NcpMessageAbortPayload>(\"agent-run.abort\"),\n sessionMessageRequest:\n createTypedKey<AgentRunSessionMessageRequestPayload>(\n \"agent-run.session-message.request\",\n ),\n },\n} as const;\n","import {\n createAgentProfile,\n findEffectiveAgentProfile,\n loadConfig,\n readAgentAvatarContent,\n removeAgentProfile,\n resolveEffectiveAgentProfiles,\n updateAgentProfile,\n type Config\n} from \"@nextclaw/core\";\nimport type { AgentCreateRequest, AgentDeleteResult, AgentProfileView, AgentUpdateRequest } from \"@nextclaw-server/shared/types/server-api.types.js\";\n\nexport function listAgents(configPath: string): AgentProfileView[] {\n const config = loadConfig(configPath);\n return resolveEffectiveAgentProfiles(config).map((profile) => toAgentProfileView(config, profile.id));\n}\n\nexport function createAgent(\n configPath: string,\n input: AgentCreateRequest,\n options: { initializeAgentHomeDirectory?: (homeDirectory: string) => void } = {}\n): AgentProfileView {\n const created = createAgentProfile(\n {\n id: input.id,\n displayName: input.displayName,\n description: input.description,\n avatar: input.avatar,\n home: input.home,\n model: input.model,\n runtime: input.runtime,\n runtimeConfig: input.runtimeConfig\n },\n {\n configPath,\n initializeHomeDirectory: options.initializeAgentHomeDirectory\n }\n );\n const config = loadConfig(configPath);\n return toAgentProfileView(config, created.id);\n}\n\nexport function deleteAgent(configPath: string, agentId: string): AgentDeleteResult | null {\n const deleted = removeAgentProfile(agentId, { configPath });\n if (!deleted) {\n return null;\n }\n return {\n deleted: true,\n agentId: agentId.trim().toLowerCase()\n };\n}\n\nexport function updateAgent(configPath: string, agentId: string, input: AgentUpdateRequest): AgentProfileView {\n const updated = updateAgentProfile(\n {\n id: agentId,\n displayName: input.displayName,\n description: input.description,\n avatar: input.avatar,\n model: input.model,\n runtime: input.runtime,\n runtimeConfig: input.runtimeConfig\n },\n { configPath }\n );\n const config = loadConfig(configPath);\n return toAgentProfileView(config, updated.id);\n}\n\nexport function readAgentAvatar(\n configPath: string,\n agentId: string\n): { bytes: Uint8Array; mimeType: string } | null {\n const config = loadConfig(configPath);\n return readAgentAvatarContent({ config, agentId });\n}\n\nexport function toAgentProfileView(config: Config, agentId: string): AgentProfileView {\n const profile = findEffectiveAgentProfile(config, agentId);\n if (!profile) {\n throw new Error(`unknown agent: ${agentId}`);\n }\n return {\n id: profile.id,\n default: profile.default,\n displayName: profile.displayName,\n description: profile.description,\n avatar: profile.avatar,\n avatarUrl: buildAgentAvatarUrl(profile.id, profile.avatar),\n workspace: profile.workspace,\n model: profile.model,\n runtime: profile.runtime,\n runtimeConfig: profile.runtimeConfig,\n engine: profile.engine,\n engineConfig: profile.engineConfig,\n contextTokens: profile.contextTokens,\n maxToolIterations: profile.maxToolIterations,\n builtIn: profile.builtIn === true\n };\n}\n\nexport function buildAgentAvatarUrl(agentId: string, avatar?: string): string | undefined {\n const normalized = typeof avatar === \"string\" ? avatar.trim() : \"\";\n if (!normalized) {\n return undefined;\n }\n if (normalized.startsWith(\"http://\") || normalized.startsWith(\"https://\")) {\n return normalized;\n }\n if (normalized.startsWith(\"home://\")) {\n return `/api/agents/${encodeURIComponent(agentId)}/avatar`;\n }\n return undefined;\n}\n","import { eventKeys } from \"@nextclaw/shared\";\nimport type { UiRouterOptions } from \"@nextclaw-server/app/types/router-options.types.js\";\n\nfunction appEventOptions() {\n return {\n emittedAt: new Date().toISOString(),\n source: \"backend\",\n };\n}\n\nexport function emitConfigUpdated(options: UiRouterOptions, path: string): void {\n options.appEventBus.emit(eventKeys.configUpdated, { path }, appEventOptions());\n}\n\nexport function emitChannelConfigApplyStatus(\n options: UiRouterOptions,\n payload: {\n channel: string;\n status: \"started\" | \"succeeded\" | \"failed\";\n message?: string;\n },\n): void {\n options.appEventBus.emit(eventKeys.channelConfigApplyStatus, payload, appEventOptions());\n}\n\nexport function emitUiError(\n options: UiRouterOptions,\n payload: {\n code?: string;\n message: string;\n },\n): void {\n options.appEventBus.emit(eventKeys.error, payload, appEventOptions());\n}\n","import type { Context } from \"hono\";\nimport { createAgent, deleteAgent, listAgents, readAgentAvatar, updateAgent } from \"@nextclaw-server/features/agents/stores/agents.store.js\";\nimport type { AgentCreateRequest, AgentUpdateRequest } from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport { err, ok, readJson } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport type { UiRouterOptions } from \"@nextclaw-server/app/types/router-options.types.js\";\nimport { emitConfigUpdated } from \"@nextclaw-server/shared/utils/app-events.utils.js\";\n\nexport class AgentsRoutesController {\n constructor(private readonly options: UiRouterOptions) {}\n\n private publishAgentUpdates = async (paths: string[]): Promise<void> => {\n for (const path of paths) {\n emitConfigUpdated(this.options, path);\n }\n await this.options.applyLiveConfigReload?.();\n };\n\n readonly listAgents = (c: Context) => {\n return c.json(ok({ agents: listAgents(this.options.configPath) }));\n };\n\n readonly createAgent = async (c: Context) => {\n const body = await readJson<AgentCreateRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n try {\n const agent = createAgent(this.options.configPath, body.data, {\n initializeAgentHomeDirectory: this.options.initializeAgentHomeDirectory\n });\n await this.publishAgentUpdates([\"agents.list\"]);\n return c.json(ok(agent));\n } catch (error) {\n return c.json(err(\"AGENT_CREATE_FAILED\", error instanceof Error ? error.message : String(error)), 400);\n }\n };\n\n readonly updateAgent = async (c: Context) => {\n const agentId = c.req.param(\"agentId\");\n const body = await readJson<AgentUpdateRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n try {\n const agent = updateAgent(this.options.configPath, agentId, body.data);\n await this.publishAgentUpdates([\"agents.list\"]);\n return c.json(ok(agent));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n const status = message.includes(\"not found\") ? 404 : 400;\n return c.json(err(\"AGENT_UPDATE_FAILED\", message), status);\n }\n };\n\n readonly deleteAgent = async (c: Context) => {\n const agentId = c.req.param(\"agentId\");\n try {\n const result = deleteAgent(this.options.configPath, agentId);\n if (!result) {\n return c.json(err(\"NOT_FOUND\", `agent not found: ${agentId}`), 404);\n }\n await this.publishAgentUpdates([\"agents.list\"]);\n return c.json(ok(result));\n } catch (error) {\n return c.json(err(\"AGENT_DELETE_FAILED\", error instanceof Error ? error.message : String(error)), 400);\n }\n };\n\n readonly getAgentAvatar = (c: Context): Response => {\n const agentId = c.req.param(\"agentId\");\n try {\n const avatar = readAgentAvatar(this.options.configPath, agentId);\n if (!avatar) {\n return c.json(err(\"NOT_FOUND\", `avatar not found for agent: ${agentId}`), 404);\n }\n return new Response(avatar.bytes, {\n headers: {\n \"content-type\": avatar.mimeType,\n \"cache-control\": \"public, max-age=300\"\n }\n });\n } catch (error) {\n return c.json(err(\"AGENT_AVATAR_FAILED\", error instanceof Error ? error.message : String(error)), 400);\n }\n };\n}\n","import type { Context } from \"hono\";\nimport type { AppMetaView, BootstrapStatusView } from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport { ok } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport type { UiRouterOptions } from \"@nextclaw-server/app/types/router-options.types.js\";\n\nfunction buildAppMetaView(options: UiRouterOptions): AppMetaView {\n const productVersion = options.productVersion?.trim();\n return {\n name: \"NextClaw\",\n productVersion: productVersion && productVersion.length > 0 ? productVersion : \"0.0.0\"\n };\n}\n\nfunction buildFallbackBootstrapStatus(): BootstrapStatusView {\n return {\n phase: \"kernel-starting\",\n ncpAgent: {\n state: \"pending\",\n },\n extensionLoading: {\n state: \"pending\",\n loadedExtensionCount: 0,\n totalExtensionCount: 0\n },\n channels: {\n state: \"pending\",\n enabled: []\n },\n remote: {\n state: \"pending\"\n }\n };\n}\n\nexport class AppRoutesController {\n constructor(private readonly options: UiRouterOptions) {}\n\n readonly health = (c: Context) =>\n c.json(\n ok({\n status: \"ok\",\n services: {\n ncpAgent: \"ready\",\n cronService: this.options.cron ? \"ready\" : \"unavailable\"\n }\n })\n );\n\n readonly appMeta = (c: Context) => c.json(ok(buildAppMetaView(this.options)));\n\n readonly bootstrapStatus = (c: Context) =>\n c.json(ok(this.options.bootstrapStatus?.getStatus() ?? buildFallbackBootstrapStatus()));\n}\n","import {\n mergeExtensionConfigView,\n toExtensionConfigView,\n type Config,\n type ConfigUiHints,\n type ExtensionChannelBinding,\n type ExtensionUiMetadata,\n} from \"@nextclaw/core\";\nimport type { ConfigMetaView } from \"@nextclaw-server/shared/types/server-api.types.js\";\n\nexport type ExtensionConfigProjectionOptions = {\n extensionChannelBindings?: ExtensionChannelBinding[];\n extensionUiMetadata?: ExtensionUiMetadata[];\n};\n\ntype ChannelTutorialUrls = NonNullable<ConfigMetaView[\"channels\"][number][\"tutorialUrls\"]>;\nconst DOCS_BASE_URL = \"https://docs.nextclaw.io\";\nconst CHANNEL_TUTORIAL_URLS: Record<string, ChannelTutorialUrls> = {\n feishu: {\n default: `${DOCS_BASE_URL}/guide/tutorials/feishu`,\n en: `${DOCS_BASE_URL}/en/guide/tutorials/feishu`,\n zh: `${DOCS_BASE_URL}/zh/guide/tutorials/feishu`\n },\n weixin: {\n default: \"https://npmx.dev/package/@nextclaw/channel-extension-weixin\"\n }\n};\n\nexport function normalizeExtensionProjectionOptions(options?: ExtensionConfigProjectionOptions): Required<ExtensionConfigProjectionOptions> {\n return {\n extensionChannelBindings: options?.extensionChannelBindings ?? [],\n extensionUiMetadata: options?.extensionUiMetadata ?? []\n };\n}\n\nexport function getProjectedConfigView(config: Config, options?: ExtensionConfigProjectionOptions): Record<string, unknown> {\n normalizeExtensionProjectionOptions(options);\n return toExtensionConfigView(config);\n}\n\nexport function getProjectedChannelMap(\n config: Config,\n options?: ExtensionConfigProjectionOptions\n): Record<string, Record<string, unknown>> {\n const view = getProjectedConfigView(config, options);\n const channels = view.channels;\n if (!channels || typeof channels !== \"object\" || Array.isArray(channels)) {\n return {};\n }\n return channels as Record<string, Record<string, unknown>>;\n}\n\nexport function getProjectedChannelConfig(\n config: Config,\n channelName: string,\n options?: ExtensionConfigProjectionOptions\n): Record<string, unknown> | null {\n const channel = getProjectedChannelMap(config, options)[channelName];\n if (!channel || typeof channel !== \"object\" || Array.isArray(channel)) {\n return null;\n }\n return channel;\n}\n\nexport function buildExtensionChannelUiHints(options?: ExtensionConfigProjectionOptions): ConfigUiHints {\n const normalized = normalizeExtensionProjectionOptions(options);\n if (normalized.extensionChannelBindings.length === 0) {\n return {};\n }\n\n const hints: ConfigUiHints = {};\n const metadataById = new Map(normalized.extensionUiMetadata.map((item) => [item.id, item]));\n\n for (const binding of normalized.extensionChannelBindings) {\n const channelScope = `channels.${binding.channelId}`;\n const channelMeta = binding.channel.meta as Record<string, unknown> | undefined;\n const channelLabel = typeof channelMeta?.selectionLabel === \"string\"\n ? channelMeta.selectionLabel\n : typeof channelMeta?.label === \"string\"\n ? channelMeta.label\n : binding.channelId;\n const channelHelp = typeof channelMeta?.blurb === \"string\" ? channelMeta.blurb : undefined;\n\n hints[channelScope] = {\n ...(channelLabel ? { label: channelLabel } : {}),\n ...(channelHelp ? { help: channelHelp } : {})\n };\n\n const extensionHints = metadataById.get(binding.extensionId)?.configUiHints ?? {};\n for (const [key, hint] of Object.entries(extensionHints)) {\n hints[`${channelScope}.${key}`] = {\n label: hint.label,\n help: hint.help,\n advanced: hint.advanced,\n sensitive: hint.sensitive,\n placeholder: hint.placeholder\n };\n }\n }\n\n return hints;\n}\n\nexport function buildProjectedChannelMeta(\n config: Config,\n options?: ExtensionConfigProjectionOptions\n): ConfigMetaView[\"channels\"] {\n const normalized = normalizeExtensionProjectionOptions(options);\n const projectedChannelMap = getProjectedChannelMap(config, normalized);\n const bindingByChannelId = new Map(normalized.extensionChannelBindings.map((binding) => [binding.channelId, binding]));\n const channelNames = new Set<string>([\n ...Object.keys(config.channels),\n ...Object.keys(projectedChannelMap),\n ...bindingByChannelId.keys()\n ]);\n\n return [...channelNames].map((name) => {\n const tutorialUrls = CHANNEL_TUTORIAL_URLS[name];\n const tutorialUrl = tutorialUrls?.default ?? tutorialUrls?.en ?? tutorialUrls?.zh;\n const binding = bindingByChannelId.get(name);\n const channelMeta = binding?.channel.meta as Record<string, unknown> | undefined;\n const displayName = typeof channelMeta?.selectionLabel === \"string\"\n ? channelMeta.selectionLabel\n : typeof channelMeta?.label === \"string\"\n ? channelMeta.label\n : name;\n\n return {\n name,\n displayName,\n enabled: Boolean(projectedChannelMap[name]?.enabled),\n tutorialUrl,\n tutorialUrls\n };\n });\n}\n\nexport function mergeProjectedExtensionChannelConfig(\n config: Config,\n channelName: string,\n mergedChannel: Record<string, unknown>,\n options?: ExtensionConfigProjectionOptions\n): Config | null {\n const normalized = normalizeExtensionProjectionOptions(options);\n if (!normalized.extensionChannelBindings.some((binding) => binding.channelId === channelName)) {\n return null;\n }\n\n const currentView = getProjectedConfigView(config, normalized);\n const nextView = {\n ...currentView,\n channels: {\n ...((currentView.channels as Record<string, unknown> | undefined) ?? {}),\n [channelName]: mergedChannel\n }\n };\n return mergeExtensionConfigView(config, nextView);\n}\n","import { saveConfig } from \"@nextclaw/core\";\nimport {\n type ExtensionChannelAuthPollResult,\n type ExtensionChannelAuthStartResult,\n type ExtensionChannelBinding\n} from \"@nextclaw/core\";\nimport { loadConfigOrDefault } from \"@nextclaw-server/features/config/index.js\";\nimport { getProjectedConfigView } from \"./extension-channel-config-projection.utils.js\";\nimport type {\n ChannelAuthPollResult,\n ChannelAuthConnectRequest,\n ChannelAuthConnectResult,\n ChannelAuthStartRequest,\n ChannelAuthStartResult\n} from \"@nextclaw-server/shared/types/server-api.types.js\";\n\nfunction cloneChannelConfig(value: unknown): Record<string, unknown> | undefined {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return undefined;\n }\n return JSON.parse(JSON.stringify(value)) as Record<string, unknown>;\n}\n\nfunction findExtensionChannelBinding(bindings: ExtensionChannelBinding[], channelId: string): ExtensionChannelBinding | null {\n const normalizedChannelId = channelId.trim().toLowerCase();\n return bindings.find((binding) => binding.channelId.trim().toLowerCase() === normalizedChannelId) ?? null;\n}\n\nfunction toPublicChannelAuthPollResult(result: ExtensionChannelAuthPollResult): ChannelAuthPollResult {\n return {\n channel: result.channel,\n status: result.status,\n message: result.message,\n nextPollMs: result.nextPollMs,\n accountId: result.accountId,\n notes: result.notes\n };\n}\n\nfunction applyAuthorizedChannelAuthResult(params: {\n configPath: string;\n binding: ExtensionChannelBinding;\n result: ExtensionChannelAuthPollResult;\n}): void {\n const { configPath, binding, result } = params;\n if (result.status !== \"authorized\" || !result.channelConfig) {\n return;\n }\n\n const currentConfig = loadConfigOrDefault(configPath);\n const nextConfig = {\n ...currentConfig,\n channels: {\n ...currentConfig.channels,\n [binding.channelId]: result.channelConfig as typeof currentConfig.channels[keyof typeof currentConfig.channels]\n }\n };\n saveConfig(nextConfig, configPath);\n}\n\nexport async function startChannelAuth(params: {\n configPath: string;\n channelId: string;\n request: ChannelAuthStartRequest;\n bindings: ExtensionChannelBinding[];\n}): Promise<ChannelAuthStartResult | null> {\n const { configPath, channelId, request, bindings } = params;\n const binding = findExtensionChannelBinding(bindings, channelId);\n const start = binding?.channel.auth?.start;\n if (!binding || !start) {\n return null;\n }\n\n const config = loadConfigOrDefault(configPath);\n const configView = getProjectedConfigView(config, {\n extensionChannelBindings: bindings\n }) as typeof config;\n const result = await start({\n cfg: configView,\n extensionId: binding.extensionId,\n channelId: binding.channelId,\n channelConfig: cloneChannelConfig(configView.channels?.[binding.channelId]),\n accountId: request.accountId?.trim() || null,\n baseUrl: request.baseUrl?.trim() || null,\n domain: request.domain?.trim() || null\n });\n\n return result satisfies ExtensionChannelAuthStartResult;\n}\n\nexport async function pollChannelAuth(params: {\n configPath: string;\n channelId: string;\n sessionId: string;\n bindings: ExtensionChannelBinding[];\n}): Promise<ChannelAuthPollResult | null> {\n const { configPath, channelId, sessionId, bindings } = params;\n const binding = findExtensionChannelBinding(bindings, channelId);\n const poll = binding?.channel.auth?.poll;\n if (!binding || !poll) {\n return null;\n }\n\n const config = loadConfigOrDefault(configPath);\n const configView = getProjectedConfigView(config, {\n extensionChannelBindings: bindings\n }) as typeof config;\n const result = await poll({\n cfg: configView,\n extensionId: binding.extensionId,\n channelId: binding.channelId,\n channelConfig: cloneChannelConfig(configView.channels?.[binding.channelId]),\n sessionId\n });\n if (!result) {\n return null;\n }\n\n applyAuthorizedChannelAuthResult({\n configPath,\n binding,\n result\n });\n return toPublicChannelAuthPollResult(result);\n}\n\nexport async function connectChannelAuth(params: {\n configPath: string;\n channelId: string;\n request: ChannelAuthConnectRequest;\n bindings: ExtensionChannelBinding[];\n}): Promise<ChannelAuthConnectResult | null> {\n const { configPath, channelId, request, bindings } = params;\n const binding = findExtensionChannelBinding(bindings, channelId);\n const connect = binding?.channel.auth?.connect;\n if (!binding || !connect) {\n return null;\n }\n\n const config = loadConfigOrDefault(configPath);\n const configView = getProjectedConfigView(config, {\n extensionChannelBindings: bindings\n }) as typeof config;\n const result = await connect({\n cfg: configView,\n extensionId: binding.extensionId,\n channelId: binding.channelId,\n channelConfig: cloneChannelConfig(configView.channels?.[binding.channelId]),\n accountId: request.accountId?.trim() || null,\n domain: request.domain?.trim() || null,\n fields: request.fields\n });\n\n applyAuthorizedChannelAuthResult({\n configPath,\n binding,\n result\n });\n return toPublicChannelAuthPollResult(result);\n}\n","import type { ProviderSpec } from '@nextclaw/core';\nimport { findBuiltinProviderByName, listBuiltinProviders } from '@nextclaw/runtime';\n\nconst MINIMAX_PORTAL_PROVIDER_SPEC: ProviderSpec = {\n name: 'minimax-portal',\n keywords: ['minimax-portal', 'minimax'],\n envKey: 'MINIMAX_PORTAL_TOKEN',\n displayName: 'MiniMax Portal',\n modelPrefix: 'minimax-portal',\n litellmPrefix: 'minimax-portal',\n skipPrefixes: ['minimax-portal/'],\n envExtras: [],\n isGateway: false,\n isLocal: false,\n detectByKeyPrefix: '',\n detectByBaseKeyword: '',\n defaultApiBase: 'https://api.minimax.io/v1',\n defaultModels: ['minimax-portal/MiniMax-M3', 'minimax-portal/MiniMax-M2.5', 'minimax-portal/MiniMax-M2.5-highspeed'],\n modelConfig: { 'minimax-portal/MiniMax-M3': { vision: true } },\n stripModelPrefix: false,\n modelOverrides: [],\n logo: 'minimax.svg',\n apiBaseHelp: {\n zh: 'OAuth Global 默认使用 https://api.minimax.io/v1;OAuth 中国区默认使用 https://api.minimaxi.com/v1。',\n en: 'OAuth Global uses https://api.minimax.io/v1 by default; OAuth CN uses https://api.minimaxi.com/v1.'\n },\n auth: {\n kind: 'device_code',\n protocol: 'minimax_user_code',\n displayName: 'MiniMax OAuth',\n baseUrl: 'https://api.minimax.io',\n deviceCodePath: '/oauth/code',\n tokenPath: '/oauth/token',\n clientId: '78257093-7e40-4613-99e0-527b14b39113',\n scope: 'group_id profile model.completion',\n grantType: 'urn:ietf:params:oauth:grant-type:user_code',\n usePkce: true,\n defaultMethodId: 'cn',\n methods: [\n {\n id: 'global',\n label: {\n zh: 'Global(海外)',\n en: 'Global'\n },\n hint: {\n zh: '适用于海外用户,默认 API Base 为 https://api.minimax.io/v1。',\n en: 'For international users. Default API base: https://api.minimax.io/v1.'\n },\n baseUrl: 'https://api.minimax.io',\n defaultApiBase: 'https://api.minimax.io/v1'\n },\n {\n id: 'cn',\n label: {\n zh: '中国区(CN)',\n en: 'China Mainland (CN)'\n },\n hint: {\n zh: '适用于中国区用户,默认 API Base 为 https://api.minimaxi.com/v1。',\n en: 'For Mainland China users. Default API base: https://api.minimaxi.com/v1.'\n },\n baseUrl: 'https://api.minimaxi.com',\n defaultApiBase: 'https://api.minimaxi.com/v1'\n }\n ],\n note: {\n zh: '通过浏览器完成 MiniMax OAuth 授权后即可使用,无需手动填写 API Key。',\n en: 'Complete MiniMax OAuth in browser to use this provider without manually entering an API key.'\n }\n }\n};\n\nconst SERVER_BUILTIN_PROVIDER_OVERRIDES: ProviderSpec[] = [MINIMAX_PORTAL_PROVIDER_SPEC];\nconst SERVER_BUILTIN_PROVIDER_OVERRIDE_MAP = new Map(SERVER_BUILTIN_PROVIDER_OVERRIDES.map((provider) => [provider.name, provider] as const));\n\nexport function listServerBuiltinProviders(): ProviderSpec[] {\n const merged = new Map<string, ProviderSpec>();\n for (const provider of listBuiltinProviders()) {\n merged.set(provider.name, provider);\n }\n for (const provider of SERVER_BUILTIN_PROVIDER_OVERRIDES) {\n merged.set(provider.name, provider);\n }\n return Array.from(merged.values());\n}\n\nexport function findServerBuiltinProviderByName(name: string): ProviderSpec | undefined {\n return SERVER_BUILTIN_PROVIDER_OVERRIDE_MAP.get(name) ?? findBuiltinProviderByName(name);\n}\n","import { createHash, randomBytes, randomUUID } from \"node:crypto\";\nimport { readFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { isAbsolute, resolve } from \"node:path\";\nimport {\n ConfigSchema,\n loadConfig,\n saveConfig,\n type ProviderConfig,\n type ProviderDeviceCodeAuthMethodSpec,\n type ProviderDeviceCodeAuthProtocol,\n type ProviderDeviceCodeAuthSpec\n} from \"@nextclaw/core\";\nimport type { ProviderAuthImportResult, ProviderAuthPollResult, ProviderAuthStartResult } from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport { findServerBuiltinProviderByName } from \"@nextclaw-server/features/config/providers/server-builtin-provider.provider.js\";\n\ntype DeviceCodeSession = {\n sessionId: string;\n providerId: string;\n providerType: string;\n configPath: string;\n authorizationCode: string;\n tokenCodeField: \"device_code\" | \"user_code\";\n protocol: ProviderDeviceCodeAuthProtocol;\n methodId?: string;\n codeVerifier?: string;\n tokenEndpoint: string;\n clientId: string;\n grantType: string;\n defaultApiBase?: string;\n expiresAtMs: number;\n intervalMs: number;\n};\n\ntype DeviceCodePayload = {\n device_code?: string;\n user_code?: string;\n verification_uri?: string;\n verification_uri_complete?: string;\n interval?: number;\n expires_in?: number;\n error?: string;\n error_description?: string;\n};\n\ntype MiniMaxCodePayload = {\n user_code?: string;\n verification_uri?: string;\n expired_in?: number;\n interval?: number;\n state?: string;\n base_resp?: {\n status_code?: number;\n status_msg?: string;\n };\n};\n\ntype TokenPayload = {\n access_token?: string;\n refresh_token?: string;\n expires_in?: number;\n error?: string;\n error_description?: string;\n};\n\ntype MiniMaxTokenPayload = {\n status?: string;\n access_token?: string | null;\n refresh_token?: string | null;\n expired_in?: number | null;\n base_resp?: {\n status_code?: number;\n status_msg?: string;\n };\n};\n\ntype ResolvedAuthMethod = {\n id?: string;\n protocol: ProviderDeviceCodeAuthProtocol;\n baseUrl: string;\n deviceCodePath: string;\n tokenPath: string;\n clientId: string;\n scope: string;\n grantType: string;\n usePkce: boolean;\n defaultApiBase?: string;\n};\n\nconst authSessions = new Map<string, DeviceCodeSession>();\nconst DEFAULT_AUTH_INTERVAL_MS = 2000;\nconst MAX_AUTH_INTERVAL_MS = 10000;\n\nfunction normalizePositiveInt(value: unknown, fallback: number): number {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value <= 0) {\n return fallback;\n }\n return Math.floor(value);\n}\n\nfunction normalizePositiveFloat(value: unknown): number | null {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value <= 0) {\n return null;\n }\n return value;\n}\n\nfunction toBase64Url(buffer: Buffer): string {\n return buffer.toString(\"base64\").replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/g, \"\");\n}\n\nfunction buildPkce(): { verifier: string; challenge: string } {\n const verifier = toBase64Url(randomBytes(48));\n const challenge = toBase64Url(createHash(\"sha256\").update(verifier).digest());\n return { verifier, challenge };\n}\n\nfunction withTrailingSlash(value: string): string {\n return value.endsWith(\"/\") ? value : `${value}/`;\n}\n\nfunction cleanupExpiredAuthSessions(now = Date.now()): void {\n for (const [sessionId, session] of authSessions.entries()) {\n if (session.expiresAtMs <= now) {\n authSessions.delete(sessionId);\n }\n }\n}\n\nfunction resolveDeviceCodeEndpoints(baseUrl: string, deviceCodePath: string, tokenPath: string): {\n deviceCodeEndpoint: string;\n tokenEndpoint: string;\n} {\n const deviceCodeEndpoint = new URL(deviceCodePath, withTrailingSlash(baseUrl)).toString();\n const tokenEndpoint = new URL(tokenPath, withTrailingSlash(baseUrl)).toString();\n return { deviceCodeEndpoint, tokenEndpoint };\n}\n\nfunction resolveAuthNote(params: {\n zh?: string;\n en?: string;\n}): string | undefined {\n return params.zh ?? params.en;\n}\n\nfunction resolveLocalizedMethodLabel(\n method: ProviderDeviceCodeAuthMethodSpec,\n fallbackId: string\n): string | undefined {\n return method.label?.zh ?? method.label?.en ?? fallbackId;\n}\n\nfunction resolveLocalizedMethodHint(method: ProviderDeviceCodeAuthMethodSpec): string | undefined {\n return method.hint?.zh ?? method.hint?.en;\n}\n\nfunction normalizeMethodId(value: string | undefined): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction resolveAuthMethod(auth: ProviderDeviceCodeAuthSpec, requestedMethodId?: string): ResolvedAuthMethod {\n const protocol = auth.protocol ?? \"rfc8628\";\n const methods = (auth.methods ?? []).filter((entry) => normalizeMethodId(entry.id));\n const cleanRequestedMethodId = normalizeMethodId(requestedMethodId);\n\n if (methods.length === 0) {\n if (cleanRequestedMethodId) {\n throw new Error(`provider auth method is not supported: ${cleanRequestedMethodId}`);\n }\n return {\n protocol,\n baseUrl: auth.baseUrl,\n deviceCodePath: auth.deviceCodePath,\n tokenPath: auth.tokenPath,\n clientId: auth.clientId,\n scope: auth.scope,\n grantType: auth.grantType,\n usePkce: Boolean(auth.usePkce)\n };\n }\n\n let selectedMethod = methods.find((entry) => normalizeMethodId(entry.id) === cleanRequestedMethodId);\n if (!selectedMethod) {\n const fallbackMethodId = normalizeMethodId(auth.defaultMethodId) ?? normalizeMethodId(methods[0]?.id);\n selectedMethod = methods.find((entry) => normalizeMethodId(entry.id) === fallbackMethodId) ?? methods[0];\n }\n const methodId = normalizeMethodId(selectedMethod?.id);\n if (!selectedMethod || !methodId) {\n throw new Error(\"provider auth method is not configured\");\n }\n if (cleanRequestedMethodId && methodId !== cleanRequestedMethodId) {\n throw new Error(`provider auth method is not supported: ${cleanRequestedMethodId}`);\n }\n\n return {\n id: methodId,\n protocol,\n baseUrl: selectedMethod.baseUrl ?? auth.baseUrl,\n deviceCodePath: selectedMethod.deviceCodePath ?? auth.deviceCodePath,\n tokenPath: selectedMethod.tokenPath ?? auth.tokenPath,\n clientId: selectedMethod.clientId ?? auth.clientId,\n scope: selectedMethod.scope ?? auth.scope,\n grantType: selectedMethod.grantType ?? auth.grantType,\n usePkce: selectedMethod.usePkce ?? Boolean(auth.usePkce),\n defaultApiBase: selectedMethod.defaultApiBase\n };\n}\n\nfunction parseExpiresAtMs(\n value: unknown,\n fallbackFromNowMs: number\n): number {\n const normalized = normalizePositiveFloat(value);\n if (normalized === null) {\n return Date.now() + fallbackFromNowMs;\n }\n if (normalized >= 1_000_000_000_000) {\n return Math.floor(normalized);\n }\n if (normalized >= 1_000_000_000) {\n return Math.floor(normalized * 1000);\n }\n return Date.now() + Math.floor(normalized * 1000);\n}\n\nfunction parsePollIntervalMs(value: unknown, fallbackMs: number): number {\n const normalized = normalizePositiveFloat(value);\n if (normalized === null) {\n return fallbackMs;\n }\n if (normalized <= 30) {\n return Math.floor(normalized * 1000);\n }\n return Math.floor(normalized);\n}\n\nfunction buildMinimaxErrorMessage(payload: unknown, fallback: string): string {\n if (!payload || typeof payload !== \"object\" || Array.isArray(payload)) {\n return fallback;\n }\n const record = payload as {\n base_resp?: { status_msg?: unknown };\n error?: unknown;\n error_description?: unknown;\n };\n if (typeof record.error_description === \"string\" && record.error_description.trim()) {\n return record.error_description.trim();\n }\n if (typeof record.error === \"string\" && record.error.trim()) {\n return record.error.trim();\n }\n const baseMessage = record.base_resp?.status_msg;\n if (typeof baseMessage === \"string\" && baseMessage.trim()) {\n return baseMessage.trim();\n }\n return fallback;\n}\n\nfunction classifyMiniMaxErrorStatus(message: string): \"denied\" | \"expired\" | \"error\" {\n const normalized = message.toLowerCase();\n if (normalized.includes(\"deny\") || normalized.includes(\"rejected\")) {\n return \"denied\";\n }\n if (normalized.includes(\"expired\") || normalized.includes(\"timeout\") || normalized.includes(\"timed out\")) {\n return \"expired\";\n }\n return \"error\";\n}\n\nfunction resolveHomePath(inputPath: string): string {\n const trimmed = inputPath.trim();\n if (!trimmed) {\n return trimmed;\n }\n if (trimmed === \"~\") {\n return homedir();\n }\n if (trimmed.startsWith(\"~/\")) {\n return resolve(homedir(), trimmed.slice(2));\n }\n if (isAbsolute(trimmed)) {\n return trimmed;\n }\n return resolve(trimmed);\n}\n\nfunction normalizeExpiresAt(value: unknown): number | null {\n if (typeof value === \"number\" && Number.isFinite(value) && value > 0) {\n return Math.floor(value);\n }\n if (typeof value === \"string\" && value.trim()) {\n const asNumber = Number(value);\n if (Number.isFinite(asNumber) && asNumber > 0) {\n return Math.floor(asNumber);\n }\n const parsedTime = Date.parse(value);\n if (Number.isFinite(parsedTime) && parsedTime > 0) {\n return parsedTime;\n }\n }\n return null;\n}\n\nfunction readFieldAsString(source: Record<string, unknown>, fieldName: string | undefined): string | null {\n if (!fieldName) {\n return null;\n }\n const rawValue = source[fieldName];\n if (typeof rawValue !== \"string\") {\n return null;\n }\n const trimmed = rawValue.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction setProviderApiKey({ configPath, provider, accessToken, defaultApiBase }: {\n configPath: string;\n provider: string;\n accessToken: string;\n defaultApiBase?: string;\n}): void {\n const config = loadConfig(configPath);\n const providers = config.providers as Record<string, ProviderConfig>;\n if (!providers[provider]) {\n return;\n }\n\n const target = providers[provider];\n target.apiKey = accessToken;\n if (defaultApiBase) {\n target.apiBase = defaultApiBase;\n }\n const next = ConfigSchema.parse(config);\n saveConfig(next, configPath);\n}\n\nfunction resolveProviderAuthTarget(configPath: string, providerId: string): {\n providerId: string;\n providerType: string;\n provider: ProviderConfig;\n} | null {\n const config = loadConfig(configPath);\n const provider = (config.providers as Record<string, ProviderConfig>)[providerId];\n if (!provider) {\n return null;\n }\n const configuredType = typeof provider.providerType === \"string\" ? provider.providerType.trim() : \"\";\n if (configuredType && findServerBuiltinProviderByName(configuredType)) {\n return { providerId, providerType: configuredType, provider };\n }\n if (findServerBuiltinProviderByName(providerId)) {\n return { providerId, providerType: providerId, provider };\n }\n return null;\n}\n\nexport async function startProviderAuth(\n configPath: string,\n providerId: string,\n options?: {\n methodId?: string;\n }\n): Promise<ProviderAuthStartResult | null> {\n cleanupExpiredAuthSessions();\n\n const target = resolveProviderAuthTarget(configPath, providerId);\n if (!target) {\n return null;\n }\n const spec = findServerBuiltinProviderByName(target.providerType);\n if (!spec?.auth || spec.auth.kind !== \"device_code\") {\n return null;\n }\n const resolvedMethod = resolveAuthMethod(spec.auth, options?.methodId);\n\n const { deviceCodeEndpoint, tokenEndpoint } = resolveDeviceCodeEndpoints(\n resolvedMethod.baseUrl,\n resolvedMethod.deviceCodePath,\n resolvedMethod.tokenPath\n );\n const pkce = resolvedMethod.usePkce ? buildPkce() : null;\n\n let authorizationCode = \"\";\n let tokenCodeField: \"device_code\" | \"user_code\" = \"device_code\";\n let userCode = \"\";\n let verificationUri = \"\";\n let intervalMs = DEFAULT_AUTH_INTERVAL_MS;\n let expiresAtMs = Date.now() + 600_000;\n\n if (resolvedMethod.protocol === \"minimax_user_code\") {\n if (!pkce) {\n throw new Error(\"MiniMax OAuth requires PKCE\");\n }\n const state = toBase64Url(randomBytes(16));\n const body = new URLSearchParams({\n response_type: \"code\",\n client_id: resolvedMethod.clientId,\n scope: resolvedMethod.scope,\n code_challenge: pkce.challenge,\n code_challenge_method: \"S256\",\n state\n });\n const response = await fetch(deviceCodeEndpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\",\n \"x-request-id\": randomUUID()\n },\n body\n });\n const payload = (await response.json().catch(() => ({}))) as MiniMaxCodePayload;\n if (!response.ok) {\n throw new Error(buildMinimaxErrorMessage(payload, response.statusText || \"MiniMax OAuth start failed\"));\n }\n if (payload.state && payload.state !== state) {\n throw new Error(\"MiniMax OAuth state mismatch\");\n }\n authorizationCode = payload.user_code?.trim() ?? \"\";\n userCode = authorizationCode;\n verificationUri = payload.verification_uri?.trim() ?? \"\";\n if (!authorizationCode || !verificationUri) {\n throw new Error(\"provider auth payload is incomplete\");\n }\n tokenCodeField = \"user_code\";\n intervalMs = Math.min(parsePollIntervalMs(payload.interval, DEFAULT_AUTH_INTERVAL_MS), MAX_AUTH_INTERVAL_MS);\n expiresAtMs = parseExpiresAtMs(payload.expired_in, 600_000);\n } else {\n const body = new URLSearchParams({\n client_id: resolvedMethod.clientId,\n scope: resolvedMethod.scope\n });\n if (pkce) {\n body.set(\"code_challenge\", pkce.challenge);\n body.set(\"code_challenge_method\", \"S256\");\n }\n const response = await fetch(deviceCodeEndpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\"\n },\n body\n });\n const payload = (await response.json().catch(() => ({}))) as DeviceCodePayload;\n if (!response.ok) {\n const message = payload.error_description || payload.error || response.statusText || \"device code auth failed\";\n throw new Error(message);\n }\n\n authorizationCode = payload.device_code?.trim() ?? \"\";\n userCode = payload.user_code?.trim() ?? \"\";\n verificationUri = payload.verification_uri_complete?.trim() || payload.verification_uri?.trim() || \"\";\n\n if (!authorizationCode || !userCode || !verificationUri) {\n throw new Error(\"provider auth payload is incomplete\");\n }\n\n intervalMs = normalizePositiveInt(payload.interval, DEFAULT_AUTH_INTERVAL_MS / 1000) * 1000;\n const expiresInSec = normalizePositiveInt(payload.expires_in, 600);\n expiresAtMs = Date.now() + expiresInSec * 1000;\n }\n\n const sessionId = randomUUID();\n\n authSessions.set(sessionId, {\n sessionId,\n providerId,\n providerType: target.providerType,\n configPath,\n authorizationCode,\n tokenCodeField,\n protocol: resolvedMethod.protocol,\n methodId: resolvedMethod.id,\n codeVerifier: pkce?.verifier,\n tokenEndpoint,\n clientId: resolvedMethod.clientId,\n grantType: resolvedMethod.grantType,\n defaultApiBase: resolvedMethod.defaultApiBase ?? spec.defaultApiBase,\n expiresAtMs,\n intervalMs\n });\n\n const methodConfig = (spec.auth.methods ?? []).find((entry) => normalizeMethodId(entry.id) === resolvedMethod.id);\n const methodLabel = methodConfig ? resolveLocalizedMethodLabel(methodConfig, resolvedMethod.id ?? \"\") : undefined;\n const methodHint = methodConfig ? resolveLocalizedMethodHint(methodConfig) : undefined;\n\n return {\n provider: providerId,\n kind: \"device_code\",\n methodId: resolvedMethod.id,\n sessionId,\n verificationUri,\n userCode,\n expiresAt: new Date(expiresAtMs).toISOString(),\n intervalMs,\n note: methodHint ?? methodLabel ?? resolveAuthNote(spec.auth.note ?? {})\n };\n}\n\nexport async function pollProviderAuth(params: {\n configPath: string;\n providerName: string;\n sessionId: string;\n}): Promise<ProviderAuthPollResult | null> {\n const { configPath, providerName: providerId, sessionId } = params;\n cleanupExpiredAuthSessions();\n\n const session = authSessions.get(sessionId);\n if (!session || session.providerId !== providerId || session.configPath !== configPath) {\n return null;\n }\n\n if (Date.now() >= session.expiresAtMs) {\n authSessions.delete(sessionId);\n return {\n provider: providerId,\n status: \"expired\",\n message: \"authorization session expired\"\n };\n }\n\n const body = new URLSearchParams({\n grant_type: session.grantType,\n client_id: session.clientId\n });\n body.set(session.tokenCodeField, session.authorizationCode);\n if (session.codeVerifier) {\n body.set(\"code_verifier\", session.codeVerifier);\n }\n\n const response = await fetch(session.tokenEndpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\"\n },\n body\n });\n let accessToken = \"\";\n\n if (session.protocol === \"minimax_user_code\") {\n const raw = await response.text();\n let payload: MiniMaxTokenPayload = {};\n if (raw) {\n try {\n payload = JSON.parse(raw) as MiniMaxTokenPayload;\n } catch {\n payload = {};\n }\n }\n if (!response.ok) {\n const message = buildMinimaxErrorMessage(payload, raw || response.statusText || \"authorization failed\");\n return {\n provider: providerId,\n status: \"error\",\n message\n };\n }\n\n const status = payload.status?.trim().toLowerCase();\n if (status === \"success\") {\n accessToken = payload.access_token?.trim() ?? \"\";\n if (!accessToken) {\n return {\n provider: providerId,\n status: \"error\",\n message: \"provider token response missing access token\"\n };\n }\n } else if (status === \"error\") {\n const message = buildMinimaxErrorMessage(payload, \"authorization failed\");\n const classified = classifyMiniMaxErrorStatus(message);\n if (classified === \"denied\" || classified === \"expired\") {\n authSessions.delete(sessionId);\n }\n return {\n provider: providerId,\n status: classified,\n message\n };\n } else {\n const nextPollMs = Math.min(Math.floor(session.intervalMs * 1.5), MAX_AUTH_INTERVAL_MS);\n session.intervalMs = nextPollMs;\n authSessions.set(sessionId, session);\n return {\n provider: providerId,\n status: \"pending\",\n nextPollMs\n };\n }\n } else {\n const payload = (await response.json().catch(() => ({}))) as TokenPayload;\n if (!response.ok) {\n const errorCode = payload.error?.trim().toLowerCase();\n if (errorCode === \"authorization_pending\") {\n return {\n provider: providerId,\n status: \"pending\",\n nextPollMs: session.intervalMs\n };\n }\n\n if (errorCode === \"slow_down\") {\n const nextPollMs = Math.min(Math.floor(session.intervalMs * 1.5), MAX_AUTH_INTERVAL_MS);\n session.intervalMs = nextPollMs;\n authSessions.set(sessionId, session);\n return {\n provider: providerId,\n status: \"pending\",\n nextPollMs\n };\n }\n\n if (errorCode === \"access_denied\") {\n authSessions.delete(sessionId);\n return {\n provider: providerId,\n status: \"denied\",\n message: payload.error_description || \"authorization denied\"\n };\n }\n\n if (errorCode === \"expired_token\") {\n authSessions.delete(sessionId);\n return {\n provider: providerId,\n status: \"expired\",\n message: payload.error_description || \"authorization session expired\"\n };\n }\n\n return {\n provider: providerId,\n status: \"error\",\n message: payload.error_description || payload.error || response.statusText || \"authorization failed\"\n };\n }\n\n accessToken = payload.access_token?.trim() ?? \"\";\n if (!accessToken) {\n return {\n provider: providerId,\n status: \"error\",\n message: \"provider token response missing access token\"\n };\n }\n }\n\n setProviderApiKey({\n configPath,\n provider: providerId,\n accessToken,\n defaultApiBase: session.defaultApiBase\n });\n\n authSessions.delete(sessionId);\n return {\n provider: providerId,\n status: \"authorized\"\n };\n}\n\nexport async function importProviderAuthFromCli(\n configPath: string,\n providerId: string\n): Promise<ProviderAuthImportResult | null> {\n const target = resolveProviderAuthTarget(configPath, providerId);\n if (!target) {\n return null;\n }\n const spec = findServerBuiltinProviderByName(target.providerType);\n if (!spec?.auth || spec.auth.kind !== \"device_code\" || !spec.auth.cliCredential) {\n return null;\n }\n\n const credentialPath = resolveHomePath(spec.auth.cliCredential.path);\n if (!credentialPath) {\n throw new Error(\"provider cli credential path is empty\");\n }\n\n let rawContent = \"\";\n try {\n rawContent = await readFile(credentialPath, \"utf8\");\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`failed to read CLI credential: ${message}`);\n }\n\n let payload: Record<string, unknown>;\n try {\n const parsed = JSON.parse(rawContent) as unknown;\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new Error(\"credential payload is not an object\");\n }\n payload = parsed as Record<string, unknown>;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`invalid CLI credential JSON: ${message}`);\n }\n\n const accessToken = readFieldAsString(payload, spec.auth.cliCredential.accessTokenField);\n if (!accessToken) {\n throw new Error(\n `CLI credential missing access token field: ${spec.auth.cliCredential.accessTokenField}`\n );\n }\n\n const expiresAtMs = normalizeExpiresAt(\n spec.auth.cliCredential.expiresAtField\n ? payload[spec.auth.cliCredential.expiresAtField]\n : undefined\n );\n if (typeof expiresAtMs === \"number\" && expiresAtMs <= Date.now()) {\n throw new Error(\"CLI credential has expired, please login again\");\n }\n\n setProviderApiKey({\n configPath,\n provider: providerId,\n accessToken,\n defaultApiBase: spec.defaultApiBase\n });\n\n return {\n provider: providerId,\n status: \"imported\",\n source: \"cli\",\n expiresAt: expiresAtMs ? new Date(expiresAtMs).toISOString() : undefined\n };\n}\n","import type { Context } from \"hono\";\nimport {\n buildConfigSchemaView,\n buildConfigMeta,\n buildConfigView,\n buildProvidersView,\n buildProviderTemplatesView,\n loadConfigOrDefault,\n executeConfigAction,\n updateChannel,\n updateModel,\n updateSearch,\n createProvider,\n deleteProvider,\n updateProvider,\n testProviderConnection,\n updateSecrets,\n updateRuntime\n} from \"@nextclaw-server/features/config/index.js\";\nimport { connectChannelAuth, pollChannelAuth, startChannelAuth } from \"@nextclaw-server/features/config/utils/channel-auth.utils.js\";\nimport { importProviderAuthFromCli, pollProviderAuth, startProviderAuth } from \"@nextclaw-server/features/config/utils/provider-auth.utils.js\";\nimport type {\n ChannelAuthPollResult,\n ChannelAuthConnectRequest,\n ChannelAuthConnectResult,\n ChannelAuthStartRequest,\n ChannelAuthStartResult,\n ConfigActionExecuteRequest,\n ProviderConnectionTestRequest,\n ProviderAuthStartRequest,\n ProviderAuthPollResult,\n ProviderAuthImportResult,\n ProviderAuthStartResult,\n ProviderCreateRequest,\n ProviderCreateResult,\n ProviderDeleteResult,\n ProviderConfigUpdate,\n SearchConfigUpdate,\n SecretsConfigUpdate,\n RuntimeConfigUpdate\n} from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport { err, ok, readJson } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport type { UiRouterOptions } from \"@nextclaw-server/app/types/router-options.types.js\";\nimport { emitChannelConfigApplyStatus, emitConfigUpdated, emitUiError } from \"@nextclaw-server/shared/utils/app-events.utils.js\";\n\nexport class ConfigRoutesController {\n private readonly channelConfigApplyTasks = new Map<string, Promise<void>>();\n\n constructor(private readonly options: UiRouterOptions) {}\n\n private readonly getExtensionConfigProjectionOptions = () => {\n return {\n extensionChannelBindings: this.options.extensions?.getChannelBindings() ?? [],\n extensionUiMetadata: this.options.extensions?.getUiMetadata() ?? []\n };\n };\n\n private readonly publishConfigUpdatedPaths = (paths: string[]): void => {\n for (const path of paths) {\n emitConfigUpdated(this.options, path);\n }\n };\n\n private readonly publishConfigUpdates = async (paths: string[]): Promise<void> => {\n this.publishConfigUpdatedPaths(paths);\n await this.options.applyLiveConfigReload?.();\n };\n\n private readonly publishChannelConfigApplyStatus = (params: {\n channel: string;\n status: \"started\" | \"succeeded\" | \"failed\";\n message?: string;\n }): void => {\n emitChannelConfigApplyStatus(this.options, params);\n };\n\n private readonly enqueueChannelConfigApply = (channel: string): void => {\n const previousTask = this.channelConfigApplyTasks.get(channel) ?? Promise.resolve();\n const task = previousTask\n .catch(() => undefined)\n .then(async () => {\n this.publishChannelConfigApplyStatus({\n channel,\n status: \"started\"\n });\n try {\n await this.options.applyLiveConfigReload?.();\n this.publishChannelConfigApplyStatus({\n channel,\n status: \"succeeded\"\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n this.publishChannelConfigApplyStatus({\n channel,\n status: \"failed\",\n message\n });\n emitUiError(this.options, {\n code: \"CHANNEL_CONFIG_APPLY_FAILED\",\n message: `Failed to apply ${channel} channel config: ${message}`\n });\n }\n })\n .finally(() => {\n if (this.channelConfigApplyTasks.get(channel) === task) {\n this.channelConfigApplyTasks.delete(channel);\n }\n });\n\n this.channelConfigApplyTasks.set(channel, task);\n void task;\n };\n\n readonly getConfig = (c: Context) => {\n const config = loadConfigOrDefault(this.options.configPath);\n return c.json(ok(buildConfigView(config, this.getExtensionConfigProjectionOptions())));\n };\n\n readonly getConfigMeta = (c: Context) => {\n const config = loadConfigOrDefault(this.options.configPath);\n return c.json(ok(buildConfigMeta(config, this.getExtensionConfigProjectionOptions())));\n };\n\n readonly listProviders = (c: Context) => {\n const config = loadConfigOrDefault(this.options.configPath);\n return c.json(ok(buildProvidersView(config)));\n };\n\n readonly listProviderTemplates = (c: Context) => {\n return c.json(ok(buildProviderTemplatesView()));\n };\n\n readonly getConfigSchema = (c: Context) => {\n const config = loadConfigOrDefault(this.options.configPath);\n return c.json(ok(buildConfigSchemaView(config, this.getExtensionConfigProjectionOptions())));\n };\n\n readonly updateConfigModel = async (c: Context) => {\n const body = await readJson<{ model?: string; workspace?: string }>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n\n const hasModel = typeof body.data.model === \"string\";\n if (!hasModel) {\n return c.json(err(\"INVALID_BODY\", \"model is required\"), 400);\n }\n\n const view = updateModel(this.options.configPath, {\n model: body.data.model,\n workspace: body.data.workspace\n });\n\n const changedPaths: string[] = [];\n if (hasModel) {\n changedPaths.push(\"agents.defaults.model\");\n }\n if (typeof body.data.workspace === \"string\") {\n changedPaths.push(\"agents.defaults.workspace\");\n }\n await this.publishConfigUpdates(changedPaths);\n\n return c.json(ok({\n model: view.agents.defaults.model,\n workspace: view.agents.defaults.workspace\n }));\n };\n\n readonly updateConfigSearch = async (c: Context) => {\n const body = await readJson<Record<string, unknown>>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n const result = updateSearch(this.options.configPath, body.data as SearchConfigUpdate);\n await this.publishConfigUpdates([\"search\"]);\n return c.json(ok(result));\n };\n\n readonly updateProvider = async (c: Context) => {\n const providerId = c.req.param(\"providerId\");\n const body = await readJson<Record<string, unknown>>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n const result = updateProvider(this.options.configPath, providerId, body.data as ProviderConfigUpdate);\n if (!result) {\n return c.json(err(\"NOT_FOUND\", `unknown provider: ${providerId}`), 404);\n }\n await this.publishConfigUpdates([`providers.${providerId}`]);\n return c.json(ok(result));\n };\n\n readonly createProvider = async (c: Context) => {\n const body = await readJson<Record<string, unknown>>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n const result = createProvider(\n this.options.configPath,\n body.data as ProviderCreateRequest\n );\n if (!result) {\n return c.json(err(\"PROVIDER_EXISTS\", \"provider already exists\"), 409);\n }\n await this.publishConfigUpdates([`providers.${result.providerId}`]);\n return c.json(ok({\n providerId: result.providerId,\n provider: result.provider\n } satisfies ProviderCreateResult));\n };\n\n readonly deleteProvider = async (c: Context) => {\n const providerId = c.req.param(\"providerId\");\n const result = deleteProvider(this.options.configPath, providerId);\n if (result === null) {\n return c.json(err(\"NOT_FOUND\", `provider not found: ${providerId}`), 404);\n }\n await this.publishConfigUpdates([`providers.${providerId}`]);\n return c.json(ok({\n deleted: true,\n providerId\n } satisfies ProviderDeleteResult));\n };\n\n readonly testProviderConnection = async (c: Context) => {\n const provider = c.req.param(\"providerId\");\n const body = await readJson<Record<string, unknown>>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n const result = await testProviderConnection(\n this.options.configPath,\n provider,\n body.data as ProviderConnectionTestRequest,\n this.options.kernel.llmProviders\n );\n if (!result) {\n return c.json(err(\"NOT_FOUND\", `unknown provider: ${provider}`), 404);\n }\n return c.json(ok(result));\n };\n\n readonly startProviderAuth = async (c: Context) => {\n const provider = c.req.param(\"providerId\");\n let payload: Record<string, unknown> = {};\n const rawBody = await c.req.raw.text();\n if (rawBody.trim().length > 0) {\n try {\n payload = JSON.parse(rawBody) as Record<string, unknown>;\n } catch {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n }\n const methodId = typeof payload.methodId === \"string\"\n ? payload.methodId.trim()\n : undefined;\n try {\n const result = await startProviderAuth(this.options.configPath, provider, {\n methodId\n } satisfies ProviderAuthStartRequest);\n if (!result) {\n return c.json(err(\"NOT_SUPPORTED\", `provider auth is not supported: ${provider}`), 404);\n }\n return c.json(ok(result satisfies ProviderAuthStartResult));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return c.json(err(\"AUTH_START_FAILED\", message), 400);\n }\n };\n\n readonly pollProviderAuth = async (c: Context) => {\n const provider = c.req.param(\"providerId\");\n const body = await readJson<Record<string, unknown>>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n const sessionId = typeof body.data.sessionId === \"string\" ? body.data.sessionId.trim() : \"\";\n if (!sessionId) {\n return c.json(err(\"INVALID_BODY\", \"sessionId is required\"), 400);\n }\n\n const result = await pollProviderAuth({\n configPath: this.options.configPath,\n providerName: provider,\n sessionId\n });\n if (!result) {\n return c.json(err(\"NOT_FOUND\", \"provider auth session not found\"), 404);\n }\n if (result.status === \"authorized\") {\n await this.publishConfigUpdates([`providers.${provider}`]);\n }\n return c.json(ok(result satisfies ProviderAuthPollResult));\n };\n\n readonly importProviderAuthFromCli = async (c: Context) => {\n const provider = c.req.param(\"providerId\");\n try {\n const result = await importProviderAuthFromCli(this.options.configPath, provider);\n if (!result) {\n return c.json(err(\"NOT_SUPPORTED\", `provider cli auth import is not supported: ${provider}`), 404);\n }\n await this.publishConfigUpdates([`providers.${provider}`]);\n return c.json(ok(result satisfies ProviderAuthImportResult));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return c.json(err(\"AUTH_IMPORT_FAILED\", message), 400);\n }\n };\n\n readonly updateChannel = async (c: Context) => {\n const channel = c.req.param(\"channel\");\n const body = await readJson<Record<string, unknown>>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n const result = updateChannel(this.options.configPath, channel, body.data, this.getExtensionConfigProjectionOptions());\n if (!result) {\n return c.json(err(\"NOT_FOUND\", `unknown channel: ${channel}`), 404);\n }\n this.publishConfigUpdatedPaths([`channels.${channel}`]);\n this.enqueueChannelConfigApply(channel);\n return c.json(ok(result));\n };\n\n readonly startChannelAuth = async (c: Context) => {\n const channel = c.req.param(\"channel\");\n let payload: Record<string, unknown> = {};\n const rawBody = await c.req.raw.text();\n if (rawBody.trim().length > 0) {\n try {\n payload = JSON.parse(rawBody) as Record<string, unknown>;\n } catch {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n }\n\n try {\n const result = await startChannelAuth({\n configPath: this.options.configPath,\n channelId: channel,\n request: {\n accountId: typeof payload.accountId === \"string\" ? payload.accountId : undefined,\n baseUrl: typeof payload.baseUrl === \"string\" ? payload.baseUrl : undefined,\n domain: typeof payload.domain === \"string\" ? payload.domain : undefined\n } satisfies ChannelAuthStartRequest,\n bindings: this.options.extensions?.getChannelBindings() ?? []\n });\n if (!result) {\n return c.json(err(\"NOT_SUPPORTED\", `channel auth is not supported: ${channel}`), 404);\n }\n return c.json(ok(result satisfies ChannelAuthStartResult));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return c.json(err(\"AUTH_START_FAILED\", message), 400);\n }\n };\n\n readonly pollChannelAuth = async (c: Context) => {\n const channel = c.req.param(\"channel\");\n const body = await readJson<Record<string, unknown>>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n const sessionId = typeof body.data.sessionId === \"string\" ? body.data.sessionId.trim() : \"\";\n if (!sessionId) {\n return c.json(err(\"INVALID_BODY\", \"sessionId is required\"), 400);\n }\n\n const result = await pollChannelAuth({\n configPath: this.options.configPath,\n channelId: channel,\n sessionId,\n bindings: this.options.extensions?.getChannelBindings() ?? []\n });\n if (!result) {\n return c.json(err(\"NOT_FOUND\", \"channel auth session not found\"), 404);\n }\n if (result.status === \"authorized\") {\n await this.publishConfigUpdates([`channels.${channel}`]);\n }\n return c.json(ok(result satisfies ChannelAuthPollResult));\n };\n\n readonly connectChannelAuth = async (c: Context) => {\n const channel = c.req.param(\"channel\");\n const body = await readJson<Record<string, unknown>>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n const fields = body.data.fields && typeof body.data.fields === \"object\" && !Array.isArray(body.data.fields)\n ? body.data.fields as Record<string, unknown>\n : {};\n\n try {\n const result = await connectChannelAuth({\n configPath: this.options.configPath,\n channelId: channel,\n request: {\n accountId: typeof body.data.accountId === \"string\" ? body.data.accountId : undefined,\n domain: typeof body.data.domain === \"string\" ? body.data.domain : undefined,\n fields\n } satisfies ChannelAuthConnectRequest,\n bindings: this.options.extensions?.getChannelBindings() ?? []\n });\n if (!result) {\n return c.json(err(\"NOT_SUPPORTED\", `channel auth connect is not supported: ${channel}`), 404);\n }\n if (result.status === \"authorized\") {\n await this.publishConfigUpdates([`channels.${channel}`]);\n }\n return c.json(ok(result satisfies ChannelAuthConnectResult));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return c.json(err(\"AUTH_CONNECT_FAILED\", message), 400);\n }\n };\n\n readonly updateSecrets = async (c: Context) => {\n const body = await readJson<Record<string, unknown>>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n const result = updateSecrets(this.options.configPath, body.data as SecretsConfigUpdate);\n await this.publishConfigUpdates([\"secrets\"]);\n return c.json(ok(result));\n };\n\n readonly updateRuntime = async (c: Context) => {\n const body = await readJson<RuntimeConfigUpdate>(c.req.raw);\n if (!body.ok || !body.data || typeof body.data !== \"object\") {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n const result = updateRuntime(this.options.configPath, body.data);\n const changedPaths: string[] = [];\n if (body.data.agents?.defaults && Object.prototype.hasOwnProperty.call(body.data.agents.defaults, \"contextTokens\")) {\n changedPaths.push(\"agents.defaults.contextTokens\");\n }\n if (body.data.agents?.defaults && Object.prototype.hasOwnProperty.call(body.data.agents.defaults, \"engine\")) {\n changedPaths.push(\"agents.defaults.engine\");\n }\n if (body.data.agents?.defaults && Object.prototype.hasOwnProperty.call(body.data.agents.defaults, \"engineConfig\")) {\n changedPaths.push(\"agents.defaults.engineConfig\");\n }\n if (body.data.agents?.runtimes && Object.prototype.hasOwnProperty.call(body.data.agents.runtimes, \"entries\")) {\n changedPaths.push(\"agents.runtimes.entries\");\n }\n if (body.data.companion && Object.prototype.hasOwnProperty.call(body.data.companion, \"enabled\")) {\n changedPaths.push(\"companion.enabled\");\n }\n changedPaths.push(\"agents.list\", \"bindings\", \"session\");\n await this.publishConfigUpdates(changedPaths);\n return c.json(ok(result));\n };\n\n readonly executeAction = async (c: Context) => {\n const actionId = c.req.param(\"actionId\");\n const body = await readJson<ConfigActionExecuteRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n const result = await executeConfigAction(this.options.configPath, actionId, body.data ?? {});\n if (!result.ok) {\n return c.json(err(result.code, result.message, result.details), 400);\n }\n return c.json(ok(result.data));\n };\n}\n","import { normalizeProviderModelConfig, type ProviderConfig, type ProviderSpec } from \"@nextclaw/core\";\n\nexport function createDefaultProviderConfig(\n defaultWireApi: \"auto\" | \"chat\" | \"responses\" = \"auto\",\n defaultModels: string[] = [],\n modelConfig: ProviderConfig[\"modelConfig\"] = {},\n providerType?: string | null,\n defaultApiBase: string | null = null\n): ProviderConfig {\n return {\n enabled: true,\n providerType,\n displayName: \"\",\n apiKey: \"\",\n apiBase: defaultApiBase,\n extraHeaders: null,\n wireApi: defaultWireApi,\n models: [...defaultModels],\n modelConfig\n };\n}\n\nexport function createDefaultProviderConfigFromSpec(spec: ProviderSpec | undefined): ProviderConfig {\n return createDefaultProviderConfig(\n spec?.defaultWireApi ?? \"auto\",\n spec?.defaultModels ?? [],\n normalizeProviderModelConfig(spec?.modelConfig ?? {}),\n spec?.name,\n spec?.defaultApiBase ?? null\n );\n}\n","import { normalizeModelThinkingCapability } from \"@nextclaw/core\";\n\nfunction normalizeOptionalString(value: unknown): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction normalizePositiveInteger(value: unknown): number | null {\n const parsed =\n typeof value === \"number\"\n ? value\n : typeof value === \"string\"\n ? Number.parseInt(value, 10)\n : Number.NaN;\n if (!Number.isFinite(parsed)) {\n return null;\n }\n const normalized = Math.trunc(parsed);\n return normalized > 0 ? normalized : null;\n}\n\nfunction normalizeStringArray(value: unknown): string[] | null {\n if (!Array.isArray(value)) {\n return null;\n }\n const entries = value\n .map((entry) => normalizeOptionalString(entry))\n .filter((entry): entry is string => Boolean(entry));\n return entries.length > 0 ? entries : null;\n}\n\nfunction normalizeUnknownStringRecord(value: unknown): Record<string, string> | null {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return null;\n }\n const entries = Object.entries(value)\n .map(([key, entryValue]) => [key.trim(), normalizeOptionalString(entryValue)] as const)\n .filter(([key, entryValue]) => key.length > 0 && Boolean(entryValue));\n return entries.length > 0 ? Object.fromEntries(entries) as Record<string, string> : null;\n}\n\nfunction normalizeRuntimeModelSelectionMode(value: unknown): string | null {\n if (value === \"nextclaw\" || value === \"optional\" || value === \"runtime-default\") {\n return value;\n }\n return null;\n}\n\nexport function normalizeRuntimeEntryConfig(\n type: string,\n config: Record<string, unknown>,\n): Record<string, unknown> {\n const runtimeDefaultThinking = normalizeModelThinkingCapability(config.runtimeDefaultThinking);\n if (type !== \"narp-stdio\") {\n const restConfig = Object.fromEntries(\n Object.entries(config).filter(([key]) => key !== \"runtimeDefaultThinking\"),\n );\n return {\n ...restConfig,\n ...(runtimeDefaultThinking ? { runtimeDefaultThinking } : {}),\n };\n }\n\n const command = normalizeOptionalString(config.command);\n const args = normalizeStringArray(config.args);\n const cwd = normalizeOptionalString(config.cwd);\n const wireDialect = normalizeOptionalString(config.wireDialect) ?? \"acp\";\n const processScope = normalizeOptionalString(config.processScope) ?? \"per-session\";\n const modelSelectionMode = normalizeRuntimeModelSelectionMode(config.modelSelectionMode);\n const supportedModels = normalizeStringArray(config.supportedModels);\n const resetSessionMetadataOnPromptTimeout = normalizeStringArray(\n config.resetSessionMetadataOnPromptTimeout,\n );\n const model = normalizeOptionalString(config.model);\n const recommendedModel = normalizeOptionalString(config.recommendedModel);\n\n return {\n wireDialect,\n processScope,\n ...(command ? { command } : {}),\n ...(args ? { args } : {}),\n env: normalizeUnknownStringRecord(config.env) ?? {},\n ...(cwd ? { cwd } : {}),\n ...(modelSelectionMode ? { modelSelectionMode } : {}),\n ...(model ? { model } : {}),\n ...(recommendedModel ? { recommendedModel } : {}),\n ...(supportedModels ? { supportedModels } : {}),\n ...(runtimeDefaultThinking ? { runtimeDefaultThinking } : {}),\n ...(resetSessionMetadataOnPromptTimeout\n ? { resetSessionMetadataOnPromptTimeout }\n : {}),\n startupTimeoutMs: normalizePositiveInteger(config.startupTimeoutMs) ?? 8000,\n probeTimeoutMs: normalizePositiveInteger(config.probeTimeoutMs) ?? 3000,\n requestTimeoutMs: normalizePositiveInteger(config.requestTimeoutMs) ?? 120000,\n };\n}\n","import {\n ConfigSchema,\n hasSecretRef,\n loadConfig,\n saveConfig,\n type Config,\n type SearchConfig\n} from \"@nextclaw/core\";\nimport type {\n BochaFreshnessValue,\n ConfigMetaView,\n ConfigView,\n SearchConfigUpdate,\n SearchProviderName,\n TavilySearchDepthValue\n} from \"@nextclaw-server/shared/types/server-api.types.js\";\n\nconst MASK_MIN_LENGTH = 8;\nconst BOCHA_OPEN_URL = \"https://open.bocha.cn\";\nconst TAVILY_DOCS_URL = \"https://docs.tavily.com/documentation/api-reference/endpoint/search\";\nconst SEARCH_PROVIDER_NAMES = [\"bocha\", \"tavily\", \"brave\"] as const;\ntype BochaSearchPatch = NonNullable<NonNullable<SearchConfigUpdate[\"providers\"]>[\"bocha\"]>;\ntype TavilySearchPatch = NonNullable<NonNullable<SearchConfigUpdate[\"providers\"]>[\"tavily\"]>;\ntype BraveSearchPatch = NonNullable<NonNullable<SearchConfigUpdate[\"providers\"]>[\"brave\"]>;\n\nfunction normalizeOptionalString(value: unknown): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction maskApiKey(value: string): { apiKeySet: boolean; apiKeyMasked?: string } {\n if (!value) {\n return { apiKeySet: false };\n }\n if (value.length < MASK_MIN_LENGTH) {\n return { apiKeySet: true, apiKeyMasked: \"****\" };\n }\n return {\n apiKeySet: true,\n apiKeyMasked: `${value.slice(0, 2)}****${value.slice(-4)}`\n };\n}\n\nfunction clearSecretRef(refs: Config[\"secrets\"][\"refs\"], path: string): Config[\"secrets\"][\"refs\"] {\n if (!refs[path]) {\n return refs;\n }\n const nextRefs = { ...refs };\n delete nextRefs[path];\n return nextRefs;\n}\n\nfunction isSearchProviderName(value: unknown): value is SearchProviderName {\n return typeof value === \"string\" && SEARCH_PROVIDER_NAMES.some((providerName) => providerName === value);\n}\n\nexport const SEARCH_PROVIDER_META: ConfigMetaView[\"search\"] = [\n {\n name: \"bocha\",\n displayName: \"Bocha Search\",\n description: \"China-friendly web search with AI-ready summaries.\",\n docsUrl: BOCHA_OPEN_URL,\n isDefault: true,\n supportsSummary: true\n },\n {\n name: \"tavily\",\n displayName: \"Tavily Search\",\n description: \"Research-focused web search with optional synthesized answers.\",\n docsUrl: TAVILY_DOCS_URL,\n supportsSummary: true\n },\n {\n name: \"brave\",\n displayName: \"Brave Search\",\n description: \"Brave web search API kept as an optional provider.\",\n supportsSummary: false\n }\n];\n\nfunction toSearchProviderView(\n config: Config,\n providerName: SearchProviderName,\n provider: SearchConfig[\"providers\"][SearchProviderName]\n): ConfigView[\"search\"][\"providers\"][\"bocha\"] {\n const apiKeyPath = `search.providers.${providerName}.apiKey`;\n const apiKeyRefSet = hasSecretRef(config, apiKeyPath);\n const masked = maskApiKey(provider.apiKey);\n const view: ConfigView[\"search\"][\"providers\"][\"bocha\"] = {\n enabled: config.search.enabledProviders.includes(providerName),\n apiKeySet: masked.apiKeySet || apiKeyRefSet,\n apiKeyMasked: masked.apiKeyMasked ?? (apiKeyRefSet ? \"****\" : undefined),\n baseUrl: provider.baseUrl\n };\n if (\"docsUrl\" in provider) {\n view.docsUrl = provider.docsUrl;\n }\n if (\"summary\" in provider) {\n view.summary = provider.summary;\n }\n if (\"freshness\" in provider) {\n view.freshness = provider.freshness as BochaFreshnessValue;\n }\n if (\"searchDepth\" in provider) {\n view.searchDepth = provider.searchDepth as TavilySearchDepthValue;\n }\n if (\"includeAnswer\" in provider) {\n view.includeAnswer = Boolean(provider.includeAnswer);\n }\n return view;\n}\n\nexport function buildSearchView(config: Config): ConfigView[\"search\"] {\n return {\n provider: config.search.provider,\n enabledProviders: [...config.search.enabledProviders],\n defaults: {\n maxResults: config.search.defaults.maxResults\n },\n providers: {\n bocha: toSearchProviderView(config, \"bocha\", config.search.providers.bocha),\n tavily: toSearchProviderView(config, \"tavily\", config.search.providers.tavily),\n brave: toSearchProviderView(config, \"brave\", config.search.providers.brave)\n }\n };\n}\n\nfunction replaceSearchConfig(\n config: Config,\n search: SearchConfig,\n refs: Config[\"secrets\"][\"refs\"] = config.secrets.refs\n): Config {\n return {\n ...config,\n search,\n secrets: refs === config.secrets.refs ? config.secrets : { ...config.secrets, refs }\n };\n}\n\nfunction applyActiveSearchProviderPatch(config: Config, provider: SearchConfigUpdate[\"provider\"]): Config {\n if (!isSearchProviderName(provider)) {\n return config;\n }\n return replaceSearchConfig(config, { ...config.search, provider });\n}\n\nfunction applyEnabledSearchProvidersPatch(config: Config, enabledProviders: SearchConfigUpdate[\"enabledProviders\"]): Config {\n if (!Array.isArray(enabledProviders)) {\n return config;\n }\n const nextEnabledProviders = Array.from(new Set(\n enabledProviders.filter((value): value is SearchProviderName => isSearchProviderName(value))\n ));\n return replaceSearchConfig(config, { ...config.search, enabledProviders: nextEnabledProviders });\n}\n\nfunction applySearchDefaultsPatch(config: Config, defaults: SearchConfigUpdate[\"defaults\"]): Config {\n if (!defaults || !Object.prototype.hasOwnProperty.call(defaults, \"maxResults\")) {\n return config;\n }\n const nextMaxResults = defaults.maxResults;\n if (typeof nextMaxResults === \"number\" && Number.isFinite(nextMaxResults)) {\n return replaceSearchConfig(config, {\n ...config.search,\n defaults: {\n ...config.search.defaults,\n maxResults: Math.max(1, Math.min(50, Math.trunc(nextMaxResults)))\n }\n });\n }\n return config;\n}\n\nfunction applyBochaSearchPatch(config: Config, patch: BochaSearchPatch | undefined): Config {\n if (!patch) {\n return config;\n }\n let nextRefs = config.secrets.refs;\n let nextProvider = config.search.providers.bocha;\n if (Object.prototype.hasOwnProperty.call(patch, \"apiKey\")) {\n nextProvider = { ...nextProvider, apiKey: patch.apiKey ?? \"\" };\n nextRefs = clearSecretRef(nextRefs, \"search.providers.bocha.apiKey\");\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"baseUrl\")) {\n nextProvider = {\n ...nextProvider,\n baseUrl: normalizeOptionalString(patch.baseUrl) ?? \"https://api.bocha.cn/v1/web-search\"\n };\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"docsUrl\")) {\n nextProvider = {\n ...nextProvider,\n docsUrl: normalizeOptionalString(patch.docsUrl) ?? BOCHA_OPEN_URL\n };\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"summary\")) {\n nextProvider = { ...nextProvider, summary: Boolean(patch.summary) };\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"freshness\")) {\n const freshness = normalizeOptionalString(patch.freshness);\n nextProvider = {\n ...nextProvider,\n freshness:\n freshness === \"noLimit\" ||\n freshness === \"oneDay\" ||\n freshness === \"oneWeek\" ||\n freshness === \"oneMonth\" ||\n freshness === \"oneYear\"\n ? freshness\n : \"noLimit\"\n };\n }\n return replaceSearchConfig(\n config,\n {\n ...config.search,\n providers: { ...config.search.providers, bocha: nextProvider }\n },\n nextRefs\n );\n}\n\nfunction applyTavilySearchPatch(config: Config, patch: TavilySearchPatch | undefined): Config {\n if (!patch) {\n return config;\n }\n let nextRefs = config.secrets.refs;\n let nextProvider = config.search.providers.tavily;\n if (Object.prototype.hasOwnProperty.call(patch, \"apiKey\")) {\n nextProvider = { ...nextProvider, apiKey: patch.apiKey ?? \"\" };\n nextRefs = clearSecretRef(nextRefs, \"search.providers.tavily.apiKey\");\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"baseUrl\")) {\n nextProvider = {\n ...nextProvider,\n baseUrl: normalizeOptionalString(patch.baseUrl) ?? \"https://api.tavily.com/search\"\n };\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"searchDepth\")) {\n const searchDepth = normalizeOptionalString(patch.searchDepth);\n nextProvider = {\n ...nextProvider,\n searchDepth: searchDepth === \"advanced\" ? \"advanced\" : \"basic\"\n };\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"includeAnswer\")) {\n nextProvider = { ...nextProvider, includeAnswer: Boolean(patch.includeAnswer) };\n }\n return replaceSearchConfig(\n config,\n {\n ...config.search,\n providers: { ...config.search.providers, tavily: nextProvider }\n },\n nextRefs\n );\n}\n\nfunction applyBraveSearchPatch(config: Config, patch: BraveSearchPatch | undefined): Config {\n if (!patch) {\n return config;\n }\n let nextRefs = config.secrets.refs;\n let nextProvider = config.search.providers.brave;\n if (Object.prototype.hasOwnProperty.call(patch, \"apiKey\")) {\n nextProvider = { ...nextProvider, apiKey: patch.apiKey ?? \"\" };\n nextRefs = clearSecretRef(nextRefs, \"search.providers.brave.apiKey\");\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"baseUrl\")) {\n nextProvider = {\n ...nextProvider,\n baseUrl: normalizeOptionalString(patch.baseUrl) ?? \"https://api.search.brave.com/res/v1/web/search\"\n };\n }\n return replaceSearchConfig(\n config,\n {\n ...config.search,\n providers: { ...config.search.providers, brave: nextProvider }\n },\n nextRefs\n );\n}\n\nexport function updateSearch(configPath: string, patch: SearchConfigUpdate): ConfigView[\"search\"] {\n const config = loadConfig(configPath);\n const nextConfig = applyBraveSearchPatch(\n applyTavilySearchPatch(\n applyBochaSearchPatch(\n applySearchDefaultsPatch(\n applyEnabledSearchProvidersPatch(\n applyActiveSearchProviderPatch(config, patch.provider),\n patch.enabledProviders\n ),\n patch.defaults\n ),\n patch.providers?.bocha\n ),\n patch.providers?.tavily\n ),\n patch.providers?.brave\n );\n const next = ConfigSchema.parse(nextConfig);\n saveConfig(next, configPath);\n return buildSearchView(next);\n}\n","import {\n loadConfig,\n saveConfig,\n ConfigSchema,\n DEFAULT_WORKSPACE_PATH,\n probeFeishu,\n type Config,\n type ConfigActionExecuteRequest,\n type ConfigActionExecuteResult,\n type ConfigActionManifest,\n type ConfigUiHint,\n type ConfigUiHints,\n type ProviderConfig,\n buildConfigSchema,\n getProviderName,\n getPackageVersion,\n hasSecretRef,\n isSensitiveConfigPath,\n type ProviderSpec,\n normalizeProviderModelConfig\n} from \"@nextclaw/core\";\nimport type { LlmProviderManager } from \"@nextclaw/kernel\";\nimport {\n buildExtensionChannelUiHints,\n buildProjectedChannelMeta,\n getProjectedChannelConfig,\n getProjectedChannelMap,\n mergeProjectedExtensionChannelConfig,\n normalizeExtensionProjectionOptions,\n type ExtensionConfigProjectionOptions\n} from \"@nextclaw-server/features/config/utils/extension-channel-config-projection.utils.js\";\nimport { createDefaultProviderConfigFromSpec } from \"@nextclaw-server/features/config/utils/default-provider-config.utils.js\";\nimport { findServerBuiltinProviderByName, listServerBuiltinProviders } from \"@nextclaw-server/features/config/providers/server-builtin-provider.provider.js\";\nimport { normalizeRuntimeEntryConfig } from \"@nextclaw-server/features/config/utils/runtime-entry-config.utils.js\";\nimport { buildSearchView, SEARCH_PROVIDER_META } from \"@nextclaw-server/features/config/utils/search-config.utils.js\";\nimport type {\n ConfigMetaView,\n RuntimeConfigUpdate,\n ConfigSchemaResponse,\n ConfigView,\n ProviderCreateRequest,\n ProviderConfigUpdate,\n ProviderConnectionTestRequest,\n ProviderConnectionTestResult,\n ProviderConfigView,\n ProviderInstanceView,\n ProvidersView,\n ProviderTemplatesView,\n SecretsConfigUpdate,\n SecretsView\n} from \"@nextclaw-server/shared/types/server-api.types.js\";\nexport { updateSearch } from \"@nextclaw-server/features/config/utils/search-config.utils.js\";\n\nconst MASK_MIN_LENGTH = 8;\nconst EXTRA_SENSITIVE_PATH_PATTERNS = [/authorization/i, /cookie/i, /session/i, /bearer/i];\nconst PREFERRED_PROVIDER_ORDER = [\n \"nextclaw\",\n \"openai\", \"anthropic\", \"gemini\", \"openrouter\", \"dashscope-coding-plan\", \"dashscope\", \"deepseek\", \"minimax\",\n \"moonshot\", \"kimi-coding\",\n \"zhipu\"\n] as const;\n\nconst PREFERRED_PROVIDER_ORDER_INDEX: Map<string, number> = new Map(\n PREFERRED_PROVIDER_ORDER.map((name, index) => [name, index])\n);\nconst BUILTIN_PROVIDERS = listServerBuiltinProviders();\nconst BUILTIN_PROVIDER_NAMES = new Set(BUILTIN_PROVIDERS.map((spec) => spec.name));\nconst CUSTOM_PROVIDER_PREFIX = \"custom-\";\nconst PROVIDER_TEST_MAX_TOKENS = 16;\n\nfunction normalizeOptionalDisplayName(value: unknown): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction isCustomProviderName(name: string): boolean {\n return name.trim().length > 0 && !BUILTIN_PROVIDER_NAMES.has(name);\n}\n\nfunction resolveCustomProviderFallbackDisplayName(name: string): string {\n if (name.startsWith(CUSTOM_PROVIDER_PREFIX)) {\n const suffix = name.slice(CUSTOM_PROVIDER_PREFIX.length);\n if (/^\\d+$/.test(suffix)) {\n return `Custom ${suffix}`;\n }\n }\n return name;\n}\n\nfunction resolveProviderInstanceDisplayName(\n providerId: string,\n provider: ProviderConfig | undefined,\n spec?: ProviderSpec | null\n): string | undefined {\n const configDisplayName = normalizeOptionalDisplayName(provider?.displayName);\n return configDisplayName ?? spec?.displayName ?? (providerId.startsWith(CUSTOM_PROVIDER_PREFIX)\n ? resolveCustomProviderFallbackDisplayName(providerId)\n : providerId);\n}\n\nfunction findNextCustomProviderName(config: Config): string {\n const providers = config.providers as Record<string, ProviderConfig>;\n let index = 1;\n while (providers[`${CUSTOM_PROVIDER_PREFIX}${index}`]) {\n index += 1;\n }\n return `${CUSTOM_PROVIDER_PREFIX}${index}`;\n}\n\nfunction normalizeProviderId(value: unknown): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n if (!trimmed || trimmed.includes(\"/\")) {\n return null;\n }\n return trimmed;\n}\n\nfunction resolveProviderType(providerId: string, provider?: ProviderConfig | null): string | null {\n const configuredType = normalizeProviderId(provider?.providerType);\n if (configuredType && findServerBuiltinProviderByName(configuredType)) {\n return configuredType;\n }\n if (findServerBuiltinProviderByName(providerId)) {\n return providerId;\n }\n return null;\n}\n\nfunction findNextProviderId(config: Config, baseProviderId: string): string {\n const providers = config.providers as Record<string, ProviderConfig>;\n let providerId = baseProviderId;\n let index = 2;\n while (providers[providerId]) {\n providerId = `${baseProviderId}-${index}`;\n index += 1;\n }\n return providerId;\n}\n\nfunction resolveProviderDisplayNameSuffix(providerId: string, baseProviderId: string): string {\n if (providerId === baseProviderId) {\n return \"\";\n }\n const suffix = providerId.slice(baseProviderId.length + 1).trim();\n return suffix ? ` ${suffix}` : \"\";\n}\n\nfunction buildProviderScopedModels(providerId: string, models: string[]): string[] {\n return normalizeModelList(models).map((model) => {\n const slashIndex = model.indexOf(\"/\");\n const modelSuffix = slashIndex >= 0 ? model.slice(slashIndex + 1).trim() : model;\n return modelSuffix ? `${providerId}/${modelSuffix}` : \"\";\n }).filter(Boolean);\n}\n\nfunction clearSecretRefsByPrefix(refs: Config[\"secrets\"][\"refs\"], pathPrefix: string): Config[\"secrets\"][\"refs\"] {\n return Object.fromEntries(Object.entries(refs).filter(([key]) => key !== pathPrefix && !key.startsWith(`${pathPrefix}.`)));\n}\ntype ExecuteActionResult =\n | { ok: true; data: ConfigActionExecuteResult }\n | { ok: false; code: string; message: string; details?: Record<string, unknown> };\n\ntype ActionHandler = (\n params: {\n config: Config;\n action: ConfigActionManifest;\n }\n) => Promise<ConfigActionExecuteResult>;\n\nfunction matchesExtraSensitivePath(path: string): boolean {\n return path !== \"session\" &&\n !path.startsWith(\"session.\") &&\n !/^agents\\.runtimes\\.entries\\.[^.]+\\.config\\.resetSessionMetadataOnPromptTimeout$/.test(path) &&\n EXTRA_SENSITIVE_PATH_PATTERNS.some((pattern) => pattern.test(path));\n}\n\nfunction matchHint(path: string, hints: ConfigUiHints): ConfigUiHint | undefined {\n const direct = hints[path];\n if (direct) {\n return direct;\n }\n const segments = path.split(\".\");\n for (const [hintKey, hint] of Object.entries(hints)) {\n if (!hintKey.includes(\"*\")) {\n continue;\n }\n const hintSegments = hintKey.split(\".\");\n if (hintSegments.length !== segments.length) {\n continue;\n }\n let match = true;\n for (let index = 0; index < segments.length; index += 1) {\n if (hintSegments[index] !== \"*\" && hintSegments[index] !== segments[index]) {\n match = false;\n break;\n }\n }\n if (match) {\n return hint;\n }\n }\n return undefined;\n}\n\nfunction isSensitivePath(path: string, hints?: ConfigUiHints): boolean {\n if (hints) {\n const hint = matchHint(path, hints);\n if (hint?.sensitive !== undefined) {\n return Boolean(hint.sensitive);\n }\n }\n return isSensitiveConfigPath(path) || matchesExtraSensitivePath(path);\n}\n\nfunction sanitizePublicConfigValue<T>(value: T, prefix: string, hints?: ConfigUiHints): T {\n if (Array.isArray(value)) {\n const nextPath = prefix ? `${prefix}[]` : \"[]\";\n return value.map((entry) => sanitizePublicConfigValue(entry, nextPath, hints)) as T;\n }\n if (!value || typeof value !== \"object\") {\n return value;\n }\n const output: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value as Record<string, unknown>)) {\n const nextPath = prefix ? `${prefix}.${key}` : key;\n if (isSensitivePath(nextPath, hints)) {\n continue;\n }\n output[key] = sanitizePublicConfigValue(val, nextPath, hints);\n }\n return output as T;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction deepMerge(base: unknown, patch: unknown): unknown {\n if (!isObject(base) || !isObject(patch)) {\n return patch;\n }\n const result: Record<string, unknown> = { ...base };\n for (const [key, value] of Object.entries(patch)) {\n const previous = result[key];\n result[key] = deepMerge(previous, value);\n }\n return result;\n}\n\nfunction getPathValue(source: unknown, path: string): unknown {\n if (!source || typeof source !== \"object\") {\n return undefined;\n }\n const segments = path.split(\".\");\n let current: unknown = source;\n for (const segment of segments) {\n if (!current || typeof current !== \"object\") {\n return undefined;\n }\n current = (current as Record<string, unknown>)[segment];\n }\n return current;\n}\n\nfunction setPathValue(target: Record<string, unknown>, path: string, value: unknown): void {\n const segments = path.split(\".\");\n if (segments.length === 0) {\n return;\n }\n let current: Record<string, unknown> = target;\n for (let index = 0; index < segments.length - 1; index += 1) {\n const segment = segments[index];\n const next = current[segment];\n if (!isObject(next)) {\n current[segment] = {};\n }\n current = current[segment] as Record<string, unknown>;\n }\n current[segments[segments.length - 1]] = value;\n}\n\nfunction isMissingRequiredValue(value: unknown): boolean {\n if (value === undefined || value === null) {\n return true;\n }\n if (typeof value === \"string\") {\n return value.trim().length === 0;\n }\n if (Array.isArray(value)) {\n return value.length === 0;\n }\n return false;\n}\n\nfunction resolveRuntimeConfig(config: Config, draftConfig?: Record<string, unknown>): Config {\n if (!draftConfig || Object.keys(draftConfig).length === 0) {\n return config;\n }\n const merged = deepMerge(config, draftConfig);\n return ConfigSchema.parse(merged);\n}\n\nfunction getActionById(config: Config, actionId: string): ConfigActionManifest | null {\n const actions = buildConfigSchemaView(config).actions;\n return actions.find((item) => item.id === actionId) ?? null;\n}\n\nfunction messageOrDefault(\n action: ConfigActionManifest,\n kind: \"success\" | \"failure\",\n fallback: string\n): string {\n const text = kind === \"success\" ? action.success?.message : action.failure?.message;\n return text?.trim() ? text : fallback;\n}\n\nasync function runFeishuVerifyAction(params: {\n config: Config;\n action: ConfigActionManifest;\n}): Promise<ConfigActionExecuteResult> {\n const { config, action } = params;\n const appId = String(config.channels.feishu.appId ?? \"\").trim();\n const appSecret = String(config.channels.feishu.appSecret ?? \"\").trim();\n if (!appId || !appSecret) {\n return {\n ok: false,\n status: \"failed\",\n message: messageOrDefault(action, \"failure\", \"Verification failed: missing credentials\"),\n data: {\n error: \"missing credentials (appId, appSecret)\"\n },\n nextActions: []\n };\n }\n\n const result = await probeFeishu(appId, appSecret);\n if (!result.ok) {\n return {\n ok: false,\n status: \"failed\",\n message: `${messageOrDefault(action, \"failure\", \"Verification failed\")}: ${result.error}`,\n data: {\n error: result.error,\n appId: result.appId ?? appId\n },\n nextActions: []\n };\n }\n\n const responseData: Record<string, unknown> = {\n appId: result.appId,\n botName: result.botName ?? null,\n botOpenId: result.botOpenId ?? null\n };\n\n const patch: Record<string, unknown> = {};\n for (const [targetPath, sourcePath] of Object.entries(action.resultMap ?? {})) {\n const mappedValue = sourcePath.startsWith(\"response.data.\")\n ? responseData[sourcePath.slice(\"response.data.\".length)]\n : undefined;\n if (mappedValue !== undefined) {\n setPathValue(patch, targetPath, mappedValue);\n }\n }\n\n return {\n ok: true,\n status: \"success\",\n message: messageOrDefault(\n action,\n \"success\",\n \"Verified. Please finish Feishu event subscription and app publishing before using.\"\n ),\n data: responseData,\n patch: Object.keys(patch).length > 0 ? patch : undefined,\n nextActions: []\n };\n}\n\nconst ACTION_HANDLERS: Record<string, ActionHandler> = {\n \"channels.feishu.verifyConnection\": runFeishuVerifyAction\n};\n\nfunction buildUiHints(config: Config, options?: ExtensionConfigProjectionOptions): ConfigUiHints {\n return buildConfigSchemaView(config, options).uiHints;\n}\n\nfunction maskApiKey(value: string): { apiKeySet: boolean; apiKeyMasked?: string } {\n if (!value) {\n return { apiKeySet: false };\n }\n if (value.length < MASK_MIN_LENGTH) {\n return { apiKeySet: true, apiKeyMasked: \"****\" };\n }\n return {\n apiKeySet: true,\n apiKeyMasked: `${value.slice(0, 2)}****${value.slice(-4)}`\n };\n}\n\nfunction normalizeModelList(input: string[] | null | undefined): string[] {\n if (!input || input.length === 0) {\n return [];\n }\n const deduped = new Set<string>();\n for (const item of input) {\n if (typeof item !== \"string\") {\n continue;\n }\n const trimmed = item.trim();\n if (!trimmed) {\n continue;\n }\n deduped.add(trimmed);\n }\n return [...deduped];\n}\n\nfunction toProviderView(\n config: Config,\n provider: ProviderConfig,\n providerId: string,\n uiHints: ConfigUiHints,\n spec?: ProviderSpec\n): ProviderInstanceView {\n const providerType = resolveProviderType(providerId, provider);\n const apiKeyPath = `providers.${providerId}.apiKey`;\n const apiKeyRefSet = hasSecretRef(config, apiKeyPath);\n const masked = maskApiKey(provider.apiKey);\n const extraHeaders =\n provider.extraHeaders && Object.keys(provider.extraHeaders).length > 0\n ? (sanitizePublicConfigValue(\n provider.extraHeaders,\n `providers.${providerId}.extraHeaders`,\n uiHints\n ) as Record<string, string>)\n : null;\n const view: ProviderInstanceView = {\n providerId,\n providerType,\n isBuiltInType: providerType !== null,\n isCustom: providerType === null,\n enabled: provider.enabled !== false,\n displayName: resolveProviderInstanceDisplayName(providerId, provider, spec),\n apiKeySet: masked.apiKeySet || apiKeyRefSet,\n apiKeyMasked: masked.apiKeyMasked ?? (apiKeyRefSet ? \"****\" : undefined),\n apiBase: provider.apiBase ?? null,\n extraHeaders: extraHeaders && Object.keys(extraHeaders).length > 0 ? extraHeaders : null,\n models: normalizeModelList(provider.models ?? []),\n modelConfig: normalizeProviderModelConfig(provider.modelConfig ?? {})\n };\n const supportsWireApi = Boolean(spec?.supportsWireApi) || providerType === null;\n if (supportsWireApi) {\n view.wireApi = provider.wireApi ?? spec?.defaultWireApi ?? \"auto\";\n }\n return view;\n}\n\nexport function buildConfigView(config: Config, options?: ExtensionConfigProjectionOptions): ConfigView {\n const uiHints = buildUiHints(config, options);\n const projectedChannels = getProjectedChannelMap(config, options);\n const providers: Record<string, ProviderConfigView> = {};\n for (const [providerId, provider] of Object.entries(config.providers)) {\n const providerConfig = provider as ProviderConfig;\n const spec = findServerBuiltinProviderByName(resolveProviderType(providerId, providerConfig) ?? \"\");\n providers[providerId] = toProviderView(config, providerConfig, providerId, uiHints, spec);\n }\n return {\n companion: sanitizePublicConfigValue(config.companion, \"companion\", uiHints),\n agents: sanitizePublicConfigValue(config.agents, \"agents\", uiHints),\n providers,\n search: buildSearchView(config),\n channels: sanitizePublicConfigValue(projectedChannels, \"channels\", uiHints),\n bindings: sanitizePublicConfigValue(config.bindings, \"bindings\", uiHints),\n session: sanitizePublicConfigValue(config.session, \"session\", uiHints),\n tools: sanitizePublicConfigValue(config.tools, \"tools\", uiHints),\n gateway: sanitizePublicConfigValue(config.gateway, \"gateway\", uiHints),\n ui: sanitizePublicConfigValue(config.ui, \"ui\", uiHints),\n secrets: {\n enabled: config.secrets.enabled,\n defaults: { ...config.secrets.defaults },\n providers: { ...config.secrets.providers },\n refs: { ...config.secrets.refs }\n } satisfies SecretsView\n };\n}\n\nfunction normalizeRuntimeEntries(\n entries: Record<string, unknown> | null | undefined,\n): Config[\"agents\"][\"runtimes\"][\"entries\"] {\n if (!entries || typeof entries !== \"object\" || Array.isArray(entries)) {\n return {};\n }\n\n const normalized: Config[\"agents\"][\"runtimes\"][\"entries\"] = {};\n for (const [rawId, rawEntry] of Object.entries(entries)) {\n const id = rawId.trim();\n if (!id || !rawEntry || typeof rawEntry !== \"object\" || Array.isArray(rawEntry)) {\n continue;\n }\n const entry = rawEntry as Record<string, unknown>;\n const type = normalizeOptionalString(entry.type);\n if (!type) {\n continue;\n }\n const normalizedIcon = normalizeRuntimeEntryIcon(entry.icon);\n normalized[id] = {\n enabled: typeof entry.enabled === \"boolean\" ? entry.enabled : true,\n ...(normalizeOptionalString(entry.label) ? { label: normalizeOptionalString(entry.label) ?? undefined } : {}),\n ...(normalizedIcon ? { icon: normalizedIcon } : {}),\n type,\n config: normalizeRuntimeEntryConfig(\n type,\n entry.config && typeof entry.config === \"object\" && !Array.isArray(entry.config)\n ? (entry.config as Record<string, unknown>)\n : {},\n ),\n };\n }\n return normalized;\n}\n\nfunction normalizeRuntimeEntryIcon(\n value: unknown,\n): { kind: \"image\"; src: string; alt?: string } | null {\n if (typeof value === \"string\") {\n const src = value.trim();\n return src ? { kind: \"image\", src } : null;\n }\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return null;\n }\n const src = normalizeOptionalString((value as Record<string, unknown>).src);\n if (!src) {\n return null;\n }\n const alt = normalizeOptionalString((value as Record<string, unknown>).alt);\n return {\n kind: \"image\",\n src,\n ...(alt ? { alt } : {}),\n };\n}\n\nfunction clearSecretRef(refs: Config[\"secrets\"][\"refs\"], path: string): Config[\"secrets\"][\"refs\"] {\n const { [path]: _removed, ...nextRefs } = refs;\n void _removed;\n return nextRefs;\n}\n\nexport function buildConfigMeta(config: Config, options?: ExtensionConfigProjectionOptions): ConfigMetaView {\n const channels = buildProjectedChannelMeta(config, options);\n return { search: SEARCH_PROVIDER_META, channels };\n}\n\nexport function buildProviderTemplatesView(): ProviderTemplatesView {\n const providerTemplates = BUILTIN_PROVIDERS.map((spec) => {\n return {\n id: spec.name,\n providerType: spec.name,\n displayName: spec.displayName ?? spec.name,\n apiProtocol: spec.apiProtocol,\n modelPrefix: spec.modelPrefix,\n keywords: spec.keywords,\n envKey: spec.envKey,\n isGateway: spec.isGateway,\n isLocal: spec.isLocal,\n defaultApiBase: spec.defaultApiBase,\n logo: spec.logo,\n apiBaseHelp: spec.apiBaseHelp,\n auth: spec.auth\n ? {\n kind: spec.auth.kind,\n displayName: spec.auth.displayName,\n note: spec.auth.note,\n methods: spec.auth.methods?.map((method) => ({\n id: method.id,\n label: method.label,\n hint: method.hint\n })),\n defaultMethodId: spec.auth.defaultMethodId,\n supportsCliImport: Boolean(spec.auth.cliCredential)\n }\n : undefined,\n defaultModels: normalizeModelList(spec.defaultModels ?? []),\n modelConfig: normalizeProviderModelConfig(spec.modelConfig ?? {}),\n supportsWireApi: spec.supportsWireApi,\n wireApiOptions: spec.wireApiOptions,\n defaultWireApi: spec.defaultWireApi\n };\n }).sort((left, right) => {\n const leftRank = PREFERRED_PROVIDER_ORDER_INDEX.get(left.id);\n const rightRank = PREFERRED_PROVIDER_ORDER_INDEX.get(right.id);\n if (leftRank !== undefined && rightRank !== undefined) {\n return leftRank - rightRank;\n }\n if (leftRank !== undefined) {\n return -1;\n }\n if (rightRank !== undefined) {\n return 1;\n }\n return left.id.localeCompare(right.id);\n });\n\n return { providerTemplates };\n}\n\nexport function buildProvidersView(config: Config): ProvidersView {\n const uiHints = buildUiHints(config);\n const providers: Record<string, ProviderInstanceView> = {};\n for (const [providerId, provider] of Object.entries(config.providers)) {\n const providerConfig = provider as ProviderConfig;\n const spec = findServerBuiltinProviderByName(resolveProviderType(providerId, providerConfig) ?? \"\");\n providers[providerId] = toProviderView(config, providerConfig, providerId, uiHints, spec);\n }\n return { providers };\n}\n\nexport function buildConfigSchemaView(_config: Config, options?: ExtensionConfigProjectionOptions): ConfigSchemaResponse {\n const base = buildConfigSchema({ version: getPackageVersion() });\n const extensionUiHints = buildExtensionChannelUiHints(options);\n if (Object.keys(extensionUiHints).length === 0) {\n return base;\n }\n return { ...base, uiHints: { ...base.uiHints, ...extensionUiHints } };\n}\n\nexport async function executeConfigAction(\n configPath: string,\n actionId: string,\n request: ConfigActionExecuteRequest\n): Promise<ExecuteActionResult> {\n const baseConfig = loadConfigOrDefault(configPath);\n const action = getActionById(baseConfig, actionId);\n if (!action) {\n return {\n ok: false,\n code: \"ACTION_NOT_FOUND\",\n message: `unknown action: ${actionId}`\n };\n }\n\n if (request.scope && request.scope !== action.scope) {\n return {\n ok: false,\n code: \"ACTION_SCOPE_MISMATCH\",\n message: `scope mismatch: expected ${action.scope}, got ${request.scope}`,\n details: {\n expectedScope: action.scope,\n requestScope: request.scope\n }\n };\n }\n\n const runtimeConfig = resolveRuntimeConfig(baseConfig, request.draftConfig);\n\n for (const requiredPath of action.requires ?? []) {\n const requiredValue = getPathValue(runtimeConfig, requiredPath);\n if (isMissingRequiredValue(requiredValue)) {\n return {\n ok: false,\n code: \"ACTION_PRECONDITION_FAILED\",\n message: `required field missing: ${requiredPath}`,\n details: {\n path: requiredPath\n }\n };\n }\n }\n\n const handler = ACTION_HANDLERS[action.id];\n if (!handler) {\n return {\n ok: false,\n code: \"ACTION_EXECUTION_FAILED\",\n message: `action handler not found for type ${action.type}`\n };\n }\n\n const result = await handler({\n config: runtimeConfig,\n action\n });\n\n return {\n ok: true,\n data: result\n };\n}\n\nexport function loadConfigOrDefault(configPath: string): Config {\n return loadConfig(configPath);\n}\n\nfunction createProviderForUpdate(providerId: string): ProviderConfig | null {\n const spec = findServerBuiltinProviderByName(providerId);\n if (!spec) {\n return null;\n }\n return createDefaultProviderConfigFromSpec(spec);\n}\n\nexport function updateModel(configPath: string, patch: { model?: string; workspace?: string }): ConfigView {\n const config = loadConfigOrDefault(configPath);\n\n if (typeof patch.model === \"string\") config.agents.defaults.model = patch.model;\n if (typeof patch.workspace === \"string\") {\n config.agents.defaults.workspace = normalizeOptionalString(patch.workspace) ?? DEFAULT_WORKSPACE_PATH;\n }\n\n const next = ConfigSchema.parse(config);\n saveConfig(next, configPath);\n return buildConfigView(next);\n}\n\nexport function updateProvider(\n configPath: string,\n providerId: string,\n patch: ProviderConfigUpdate\n): ProviderConfigView | null {\n const config = loadConfigOrDefault(configPath);\n const providers = config.providers as Record<string, ProviderConfig>;\n const provider = providers[providerId] ?? createProviderForUpdate(providerId);\n if (!provider) {\n return null;\n }\n providers[providerId] = provider;\n const requestedProviderType = Object.prototype.hasOwnProperty.call(patch, \"providerType\")\n ? normalizeProviderId(patch.providerType)\n : resolveProviderType(providerId, provider);\n const spec = findServerBuiltinProviderByName(requestedProviderType ?? \"\");\n if (Object.prototype.hasOwnProperty.call(patch, \"providerType\")) {\n provider.providerType = spec?.name ?? null;\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"displayName\")) {\n provider.displayName = normalizeOptionalDisplayName(patch.displayName) ?? \"\";\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"enabled\")) {\n provider.enabled = patch.enabled !== false;\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"apiKey\")) {\n provider.apiKey = patch.apiKey ?? \"\";\n config.secrets.refs = clearSecretRef(config.secrets.refs, `providers.${providerId}.apiKey`);\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"apiBase\")) {\n provider.apiBase = patch.apiBase ?? null;\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"extraHeaders\")) {\n provider.extraHeaders = patch.extraHeaders ?? null;\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"wireApi\") && (spec?.supportsWireApi || !spec)) {\n provider.wireApi = patch.wireApi ?? spec?.defaultWireApi ?? \"auto\";\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"models\")) {\n provider.models = normalizeModelList(patch.models ?? []);\n }\n if (Object.prototype.hasOwnProperty.call(patch, \"modelConfig\")) {\n provider.modelConfig = normalizeProviderModelConfig(patch.modelConfig ?? {});\n }\n const next = ConfigSchema.parse(config);\n saveConfig(next, configPath);\n const uiHints = buildUiHints(next);\n const updated = (next.providers as Record<string, ProviderConfig>)[providerId];\n return toProviderView(next, updated, providerId, uiHints, spec ?? undefined);\n}\n\nexport function createProvider(\n configPath: string,\n patch: ProviderCreateRequest = {}\n): { providerId: string; provider: ProviderConfigView } | null {\n const config = loadConfigOrDefault(configPath);\n const providers = config.providers as Record<string, ProviderConfig>;\n const requestedProviderType = normalizeProviderId(patch.providerType);\n const spec = requestedProviderType ? findServerBuiltinProviderByName(requestedProviderType) : undefined;\n const fallbackProviderId = spec ? spec.name : findNextCustomProviderName(config);\n const requestedProviderId = normalizeProviderId(patch.providerId);\n if (requestedProviderId && providers[requestedProviderId]) {\n return null;\n }\n const providerId = requestedProviderId\n ? requestedProviderId\n : findNextProviderId(config, fallbackProviderId);\n const generatedDisplayName = spec\n ? `${spec.displayName}${resolveProviderDisplayNameSuffix(providerId, spec.name)}`\n : resolveCustomProviderFallbackDisplayName(providerId);\n const defaultModels = spec ? buildProviderScopedModels(providerId, spec.defaultModels ?? []) : [];\n providers[providerId] = {\n enabled: patch.enabled !== false,\n providerType: spec?.name ?? null,\n displayName: normalizeOptionalDisplayName(patch.displayName) ?? generatedDisplayName,\n apiKey: normalizeOptionalString(patch.apiKey) ?? \"\",\n apiBase: normalizeOptionalString(patch.apiBase) ?? spec?.defaultApiBase ?? null,\n extraHeaders: normalizeHeaders(patch.extraHeaders ?? null),\n wireApi: patch.wireApi ?? spec?.defaultWireApi ?? \"auto\",\n models: Object.prototype.hasOwnProperty.call(patch, \"models\")\n ? normalizeModelList(patch.models ?? [])\n : defaultModels,\n modelConfig: normalizeProviderModelConfig(patch.modelConfig ?? spec?.modelConfig ?? {})\n };\n const next = ConfigSchema.parse(config);\n saveConfig(next, configPath);\n const uiHints = buildUiHints(next);\n const created = (next.providers as Record<string, ProviderConfig>)[providerId];\n return {\n providerId,\n provider: toProviderView(next, created, providerId, uiHints, spec)\n };\n}\n\nexport function deleteProvider(configPath: string, providerId: string): boolean | null {\n const config = loadConfigOrDefault(configPath);\n const providers = config.providers as Record<string, ProviderConfig>;\n if (!providers[providerId]) {\n return null;\n }\n delete providers[providerId];\n config.secrets.refs = clearSecretRefsByPrefix(config.secrets.refs, `providers.${providerId}`);\n const next = ConfigSchema.parse(config);\n saveConfig(next, configPath);\n return true;\n}\n\nfunction normalizeOptionalString(value: unknown): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction normalizeHeaders(input: Record<string, string> | null | undefined): Record<string, string> | null {\n if (!input) {\n return null;\n }\n const entries = Object.entries(input)\n .map(([key, value]) => [key.trim(), String(value ?? \"\").trim()] as const)\n .filter(([key, value]) => key.length > 0 && value.length > 0);\n if (entries.length === 0) {\n return null;\n }\n return Object.fromEntries(entries);\n}\n\nfunction buildScopedProviderModel(\n providerName: string,\n model: string,\n spec?: ProviderSpec\n): string {\n const trimmed = model.trim();\n if (!trimmed) {\n return \"\";\n }\n if (trimmed.includes(\"/\")) {\n return trimmed;\n }\n if (isCustomProviderName(providerName)) {\n return trimmed;\n }\n const prefix = (spec?.modelPrefix ?? providerName).trim();\n if (!prefix) {\n return trimmed;\n }\n return `${prefix}/${trimmed}`;\n}\n\nfunction stripProviderIdPrefix(providerId: string, model: string): string {\n const prefix = `${providerId}/`;\n if (!model.startsWith(prefix)) {\n return model;\n }\n const stripped = model.slice(prefix.length).trim();\n return stripped || model;\n}\n\nfunction resolveTestModel(\n config: Config,\n providerId: string,\n requestedModel: string | null,\n provider: ProviderConfig,\n spec?: ProviderSpec\n): string | null {\n if (requestedModel) {\n return spec ? requestedModel.replace(`${providerId}/`, `${spec.name}/`) : stripProviderIdPrefix(providerId, requestedModel);\n }\n\n const providerModels = normalizeModelList(provider.models ?? [])\n .map((modelId) => {\n const providerModel = stripProviderIdPrefix(providerId, modelId);\n return spec ? buildScopedProviderModel(spec.name, providerModel, spec) : providerModel;\n })\n .filter((modelId) => modelId.length > 0);\n if (providerModels.length > 0) {\n return providerModels[0];\n }\n\n const defaultModel = normalizeOptionalString(config.agents.defaults.model);\n if (defaultModel) {\n const routedProvider = getProviderName(config, defaultModel);\n if (!routedProvider || routedProvider === providerId) {\n return spec ? defaultModel.replace(`${providerId}/`, `${spec.name}/`) : stripProviderIdPrefix(providerId, defaultModel);\n }\n }\n\n if (!spec) {\n return null;\n }\n const specDefaultModel = normalizeModelList(spec?.defaultModels ?? [])[0] ?? null;\n return specDefaultModel ?? defaultModel ?? null;\n}\n\nfunction stringifyError(error: unknown): string {\n const raw = error instanceof Error ? error.message : String(error);\n return raw.replace(/\\s+/g, \" \").trim();\n}\n\nexport async function testProviderConnection(\n configPath: string,\n providerId: string,\n patch: ProviderConnectionTestRequest,\n providerManager?: LlmProviderManager\n): Promise<ProviderConnectionTestResult | null> {\n const config = loadConfigOrDefault(configPath);\n const provider = (config.providers as Record<string, ProviderConfig>)[providerId];\n if (!provider) {\n return null;\n }\n\n const providerType = resolveProviderType(providerId, provider);\n const spec = findServerBuiltinProviderByName(providerType ?? \"\");\n const hasApiKeyPatch = Object.prototype.hasOwnProperty.call(patch, \"apiKey\");\n const providedApiKey = normalizeOptionalString(patch.apiKey);\n const currentApiKey = normalizeOptionalString(provider.apiKey);\n const apiKey = hasApiKeyPatch ? providedApiKey : currentApiKey;\n\n const hasApiBasePatch = Object.prototype.hasOwnProperty.call(patch, \"apiBase\");\n const patchedApiBase = normalizeOptionalString(patch.apiBase);\n const currentApiBase = normalizeOptionalString(provider.apiBase);\n const apiBase = hasApiBasePatch\n ? patchedApiBase ?? spec?.defaultApiBase ?? null\n : currentApiBase ?? spec?.defaultApiBase ?? null;\n\n const hasHeadersPatch = Object.prototype.hasOwnProperty.call(patch, \"extraHeaders\");\n const extraHeaders = hasHeadersPatch\n ? normalizeHeaders(patch.extraHeaders ?? null)\n : normalizeHeaders(provider.extraHeaders ?? null);\n\n const wireApi = (spec?.supportsWireApi || !spec)\n ? patch.wireApi ?? provider.wireApi ?? spec?.defaultWireApi ?? \"auto\"\n : null;\n\n if (!apiKey && !spec?.isLocal) {\n return {\n success: false,\n provider: providerId,\n latencyMs: 0,\n message: \"API key is required before testing the connection.\"\n };\n }\n\n const requestedModel = normalizeOptionalString(patch.model);\n const model = resolveTestModel(config, providerId, requestedModel, provider, spec ?? undefined);\n if (!model) {\n return {\n success: false,\n provider: providerId,\n latencyMs: 0,\n message: \"No test model found. Configure provider models or set a default model for this provider, then try again.\"\n };\n }\n\n const startedAtMs = Date.now();\n if (!providerManager) {\n return {\n success: false,\n provider: providerId,\n model,\n latencyMs: Date.now() - startedAtMs,\n message: \"Provider manager is unavailable.\"\n };\n }\n try {\n await providerManager.testConnection({\n providerName: providerType,\n apiKey,\n apiBase,\n defaultModel: model,\n extraHeaders,\n wireApi,\n messages: [{ role: \"user\", content: \"ping\" }],\n maxTokens: PROVIDER_TEST_MAX_TOKENS\n });\n return {\n success: true,\n provider: providerId,\n model,\n latencyMs: Date.now() - startedAtMs,\n message: \"Connection test passed.\"\n };\n } catch (error) {\n return {\n success: false,\n provider: providerId,\n model,\n latencyMs: Date.now() - startedAtMs,\n message: stringifyError(error) || \"Connection test failed.\"\n };\n }\n}\n\nexport function updateChannel(\n configPath: string,\n channelName: string,\n patch: Record<string, unknown>,\n options?: ExtensionConfigProjectionOptions\n): Record<string, unknown> | null {\n const config = loadConfigOrDefault(configPath);\n const normalizedOptions = normalizeExtensionProjectionOptions(options);\n const channel = getProjectedChannelConfig(config, channelName, normalizedOptions);\n if (!channel) {\n return null;\n }\n for (const key of Object.keys(patch)) {\n const path = `channels.${channelName}.${key}`;\n if (isSensitivePath(path)) {\n config.secrets.refs = clearSecretRef(config.secrets.refs, path);\n }\n }\n const mergedChannel = { ...channel, ...patch };\n const mergedExtensionConfig = mergeProjectedExtensionChannelConfig(config, channelName, mergedChannel, normalizedOptions);\n if (mergedExtensionConfig) {\n const next = ConfigSchema.parse(mergedExtensionConfig);\n saveConfig(next, configPath);\n return sanitizePublicConfigValue(\n getProjectedChannelConfig(next, channelName, normalizedOptions) ?? {},\n `channels.${channelName}`,\n buildUiHints(next, normalizedOptions)\n );\n }\n\n (config.channels as Record<string, Record<string, unknown>>)[channelName] = mergedChannel;\n const next = ConfigSchema.parse(config);\n saveConfig(next, configPath);\n return sanitizePublicConfigValue(\n getProjectedChannelConfig(next, channelName, normalizedOptions) ?? {},\n `channels.${channelName}`,\n buildUiHints(next, normalizedOptions)\n );\n}\n\ntype RuntimeAgentDefaultsPatch = NonNullable<NonNullable<RuntimeConfigUpdate[\"agents\"]>[\"defaults\"]>;\n\nfunction applyRuntimeAgentDefaultsPatch(defaults: Config[\"agents\"][\"defaults\"], defaultsPatch: RuntimeAgentDefaultsPatch | undefined): Config[\"agents\"][\"defaults\"] {\n if (!defaultsPatch) return defaults;\n let next = defaults;\n if (Object.prototype.hasOwnProperty.call(defaultsPatch, \"contextTokens\")) {\n const nextContextTokens = defaultsPatch.contextTokens;\n if (typeof nextContextTokens === \"number\" && Number.isFinite(nextContextTokens)) next = { ...next, contextTokens: Math.max(1000, Math.trunc(nextContextTokens)) };\n }\n if (Object.prototype.hasOwnProperty.call(defaultsPatch, \"engine\")) next = { ...next, engine: normalizeOptionalString(defaultsPatch.engine) ?? \"native\" };\n if (Object.prototype.hasOwnProperty.call(defaultsPatch, \"engineConfig\")) {\n const nextEngineConfig = defaultsPatch.engineConfig;\n if (nextEngineConfig && typeof nextEngineConfig === \"object\" && !Array.isArray(nextEngineConfig)) next = { ...next, engineConfig: { ...nextEngineConfig } };\n }\n return next;\n}\n\nexport function updateRuntime(configPath: string, patch: RuntimeConfigUpdate): Pick<ConfigView, \"companion\" | \"agents\" | \"bindings\" | \"session\"> {\n const config = loadConfigOrDefault(configPath);\n if (patch.companion && Object.prototype.hasOwnProperty.call(patch.companion, \"enabled\")) config.companion.enabled = Boolean(patch.companion.enabled);\n config.agents.defaults = applyRuntimeAgentDefaultsPatch(config.agents.defaults, patch.agents?.defaults);\n if (patch.agents && Object.prototype.hasOwnProperty.call(patch.agents, \"list\")) {\n config.agents.list = (patch.agents.list ?? []).map((entry) => {\n const normalizedEngine = normalizeOptionalString(entry.engine);\n const hasEngineConfig =\n entry.engineConfig &&\n typeof entry.engineConfig === \"object\" &&\n !Array.isArray(entry.engineConfig);\n return {\n ...entry,\n default: Boolean(entry.default),\n ...(normalizedEngine ? { engine: normalizedEngine } : {}),\n ...(hasEngineConfig ? { engineConfig: { ...entry.engineConfig } } : {})\n };\n });\n }\n\n if (patch.agents?.runtimes && Object.prototype.hasOwnProperty.call(patch.agents.runtimes, \"entries\")) {\n config.agents.runtimes.entries = normalizeRuntimeEntries(\n patch.agents.runtimes.entries as Record<string, unknown> | null | undefined,\n );\n }\n\n if (Object.prototype.hasOwnProperty.call(patch, \"bindings\")) {\n config.bindings = patch.bindings ?? [];\n }\n\n if (patch.session) {\n config.session = {\n ...config.session,\n ...patch.session\n };\n }\n\n const next = ConfigSchema.parse(config);\n saveConfig(next, configPath);\n const view = buildConfigView(next);\n return {\n companion: view.companion,\n agents: view.agents,\n bindings: view.bindings ?? [],\n session: view.session ?? {}\n };\n}\n\nexport function updateSecrets(\n configPath: string,\n patch: SecretsConfigUpdate\n): SecretsView {\n const config = loadConfigOrDefault(configPath);\n\n if (Object.prototype.hasOwnProperty.call(patch, \"enabled\")) {\n config.secrets.enabled = Boolean(patch.enabled);\n }\n\n if (patch.defaults) {\n const nextDefaults = { ...config.secrets.defaults };\n for (const source of [\"env\", \"file\", \"exec\"] as const) {\n if (!Object.prototype.hasOwnProperty.call(patch.defaults, source)) {\n continue;\n }\n const value = patch.defaults[source];\n if (typeof value === \"string\" && value.trim()) {\n nextDefaults[source] = value.trim();\n } else {\n delete nextDefaults[source];\n }\n }\n config.secrets.defaults = nextDefaults;\n }\n\n if (Object.prototype.hasOwnProperty.call(patch, \"providers\")) {\n config.secrets.providers = (patch.providers ?? {}) as Config[\"secrets\"][\"providers\"];\n }\n\n if (Object.prototype.hasOwnProperty.call(patch, \"refs\")) {\n config.secrets.refs = (patch.refs ?? {}) as Config[\"secrets\"][\"refs\"];\n }\n\n const next = ConfigSchema.parse(config);\n saveConfig(next, configPath);\n return {\n enabled: next.secrets.enabled,\n defaults: { ...next.secrets.defaults },\n providers: { ...next.secrets.providers },\n refs: { ...next.secrets.refs }\n };\n}\n","import type { Context } from \"hono\";\nimport type {\n CronActionResult,\n CronCreateRequest,\n CronCreateResult,\n CronEnableRequest,\n CronJobView,\n CronRunRequest\n} from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport { err, ok, readJson, readNonEmptyString } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport type { CronJobEntry, UiCronHost, UiRouterOptions } from \"@nextclaw-server/app/types/router-options.types.js\";\n\nfunction toIsoTime(value?: number | null): string | null {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n return null;\n }\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) {\n return null;\n }\n return date.toISOString();\n}\n\nfunction buildCronJobView(job: CronJobEntry): CronJobView {\n return {\n id: job.id,\n name: job.name,\n enabled: job.enabled,\n schedule: job.schedule,\n payload: job.payload,\n state: {\n nextRunAt: toIsoTime(job.state.nextRunAtMs),\n lastRunAt: toIsoTime(job.state.lastRunAtMs),\n lastStatus: job.state.lastStatus ?? null,\n lastError: job.state.lastError ?? null\n },\n createdAt: new Date(job.createdAtMs).toISOString(),\n updatedAt: new Date(job.updatedAtMs).toISOString(),\n deleteAfterRun: job.deleteAfterRun\n };\n}\n\nfunction findCronJob(service: UiCronHost, id: string): CronJobEntry | null {\n const jobs = service.listJobs(true);\n return jobs.find((job) => job.id === id) ?? null;\n}\n\ntype CronCreateParams = Parameters<UiCronHost[\"addJob\"]>[0];\ntype CronCreateInput = CronCreateRequest & Record<string, unknown>;\nconst legacyCronDeliveryKeys = [\"deliver\", \"channel\", \"to\", \"accountId\", \"account_id\"] as const;\n\nfunction normalizeCronSchedule(schedule: CronCreateRequest[\"schedule\"] | undefined): CronJobEntry[\"schedule\"] | null {\n if (!schedule) {\n return null;\n }\n if (schedule.kind === \"every\") {\n if (typeof schedule.everyMs !== \"number\" || !Number.isFinite(schedule.everyMs) || schedule.everyMs <= 0) {\n return null;\n }\n return { kind: \"every\", everyMs: schedule.everyMs };\n }\n if (schedule.kind === \"at\") {\n if (typeof schedule.atMs !== \"number\" || !Number.isFinite(schedule.atMs)) {\n return null;\n }\n return { kind: \"at\", atMs: schedule.atMs };\n }\n if (schedule.kind === \"cron\") {\n const expr = readNonEmptyString(schedule.expr);\n if (!expr) {\n return null;\n }\n const tz = readNonEmptyString(schedule.tz);\n return tz ? { kind: \"cron\", expr, tz } : { kind: \"cron\", expr };\n }\n return null;\n}\n\nfunction readLegacyDeliveryKey(input: Record<string, unknown>): string | null {\n return legacyCronDeliveryKeys.find((key) => input[key] !== undefined) ?? null;\n}\n\nfunction readCronCreateParams(input: CronCreateInput): { params: CronCreateParams } | { error: string } {\n const legacyDeliveryKey = readLegacyDeliveryKey(input);\n if (legacyDeliveryKey) {\n return { error: `cron jobs do not accept ${legacyDeliveryKey}; put delivery instructions in message and use the message tool at run time` };\n }\n const name = readNonEmptyString(input.name);\n if (!name) {\n return { error: \"name must be a non-empty string\" };\n }\n const message = readNonEmptyString(input.message);\n if (!message) {\n return { error: \"message must be a non-empty string\" };\n }\n const schedule = normalizeCronSchedule(input.schedule);\n if (!schedule) {\n return { error: \"schedule must be a valid at/every/cron definition\" };\n }\n return {\n params: {\n name,\n message,\n schedule,\n agentId: readNonEmptyString(input.agentId),\n sessionId: readNonEmptyString(input.sessionId),\n deleteAfterRun: input.deleteAfterRun === true\n }\n };\n}\n\nexport class CronRoutesController {\n constructor(private readonly options: UiRouterOptions) {}\n\n readonly listJobs = (c: Context) => {\n if (!this.options.cron) {\n return c.json(err(\"NOT_AVAILABLE\", \"cron service unavailable\"), 503);\n }\n const query = c.req.query();\n const enabledOnly =\n query.enabledOnly === \"1\" ||\n query.enabledOnly === \"true\" ||\n query.enabledOnly === \"yes\" ||\n query.all === \"0\" ||\n query.all === \"false\" ||\n query.all === \"no\";\n const includeDisabled = !enabledOnly;\n const jobs = this.options.cron.listJobs(includeDisabled).map((job) => buildCronJobView(job as CronJobEntry));\n return c.json(ok({ jobs, total: jobs.length }));\n };\n\n readonly createJob = async (c: Context) => {\n if (!this.options.cron) {\n return c.json(err(\"NOT_AVAILABLE\", \"cron service unavailable\"), 503);\n }\n const body = await readJson<CronCreateInput>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n const normalized = readCronCreateParams(body.data);\n if (\"error\" in normalized) {\n return c.json(err(\"INVALID_BODY\", normalized.error), 400);\n }\n const job = this.options.cron.addJob(normalized.params);\n const data: CronCreateResult = { job: buildCronJobView(job as CronJobEntry) };\n return c.json(ok(data), 201);\n };\n\n readonly deleteJob = (c: Context) => {\n if (!this.options.cron) {\n return c.json(err(\"NOT_AVAILABLE\", \"cron service unavailable\"), 503);\n }\n const id = decodeURIComponent(c.req.param(\"id\"));\n const deleted = this.options.cron.removeJob(id);\n if (!deleted) {\n return c.json(err(\"NOT_FOUND\", `cron job not found: ${id}`), 404);\n }\n return c.json(ok({ deleted: true }));\n };\n\n readonly enableJob = async (c: Context) => {\n if (!this.options.cron) {\n return c.json(err(\"NOT_AVAILABLE\", \"cron service unavailable\"), 503);\n }\n const id = decodeURIComponent(c.req.param(\"id\"));\n const body = await readJson<CronEnableRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n if (typeof body.data.enabled !== \"boolean\") {\n return c.json(err(\"INVALID_BODY\", \"enabled must be boolean\"), 400);\n }\n const job = this.options.cron.enableJob(id, body.data.enabled);\n if (!job) {\n return c.json(err(\"NOT_FOUND\", `cron job not found: ${id}`), 404);\n }\n const data: CronActionResult = { job: buildCronJobView(job as CronJobEntry) };\n return c.json(ok(data));\n };\n\n readonly runJob = async (c: Context) => {\n if (!this.options.cron) {\n return c.json(err(\"NOT_AVAILABLE\", \"cron service unavailable\"), 503);\n }\n const id = decodeURIComponent(c.req.param(\"id\"));\n const body = await readJson<CronRunRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n const existing = findCronJob(this.options.cron, id);\n if (!existing) {\n return c.json(err(\"NOT_FOUND\", `cron job not found: ${id}`), 404);\n }\n const executed = await this.options.cron.runJob(id, Boolean(body.data.force));\n const after = findCronJob(this.options.cron, id);\n const data: CronActionResult = {\n job: after ? buildCronJobView(after) : null,\n executed\n };\n return c.json(ok(data));\n };\n}\n","import { readFile } from \"node:fs/promises\";\nimport type { Context } from \"hono\";\nimport type { UiNcpAssetPutView, UiNcpAssetView } from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport { err, ok } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport type { UiRouterOptions } from \"@nextclaw-server/app/types/router-options.types.js\";\n\nconst ASSET_CONTENT_BASE_PATH = \"/api/ncp/assets/content\";\n\nfunction buildAssetContentUrl(assetUri: string): string {\n const query = new URLSearchParams({ uri: assetUri });\n return `${ASSET_CONTENT_BASE_PATH}?${query.toString()}`;\n}\n\nfunction encodeContentDispositionFileName(fileName: string): string {\n return encodeURIComponent(fileName).replace(/\\*/g, \"%2A\");\n}\n\nfunction inferMimeTypeFromFileName(fileName: string): string | null {\n const normalized = fileName.trim().toLowerCase();\n if (normalized.endsWith(\".mp3\")) return \"audio/mpeg\";\n if (normalized.endsWith(\".m4a\")) return \"audio/mp4\";\n if (normalized.endsWith(\".wav\")) return \"audio/wav\";\n if (normalized.endsWith(\".ogg\")) return \"audio/ogg\";\n if (normalized.endsWith(\".opus\")) return \"audio/opus\";\n if (normalized.endsWith(\".flac\")) return \"audio/flac\";\n if (normalized.endsWith(\".aac\")) return \"audio/aac\";\n if (normalized.endsWith(\".weba\")) return \"audio/webm\";\n if (normalized.endsWith(\".mp4\") || normalized.endsWith(\".m4v\")) return \"video/mp4\";\n if (normalized.endsWith(\".mov\")) return \"video/quicktime\";\n if (normalized.endsWith(\".webm\")) return \"video/webm\";\n if (normalized.endsWith(\".mkv\")) return \"video/x-matroska\";\n if (normalized.endsWith(\".avi\")) return \"video/x-msvideo\";\n if (normalized.endsWith(\".wmv\")) return \"video/x-ms-wmv\";\n return null;\n}\n\nfunction resolveResponseMimeType(fileName: string, mimeType: string): string {\n const normalized = mimeType.trim().toLowerCase();\n if (normalized.length > 0 && normalized !== \"application/octet-stream\") {\n return normalized;\n }\n return inferMimeTypeFromFileName(fileName) ?? \"application/octet-stream\";\n}\n\nfunction toAssetView(record: {\n id: string;\n uri: string;\n fileName: string;\n mimeType: string;\n sizeBytes: number;\n}): UiNcpAssetView {\n return {\n id: record.id,\n name: record.fileName,\n mimeType: record.mimeType,\n sizeBytes: record.sizeBytes,\n assetUri: record.uri,\n url: buildAssetContentUrl(record.uri),\n };\n}\n\nexport class NcpAssetRoutesController {\n constructor(private readonly options: UiRouterOptions) {}\n\n private readonly getAssetApi = () => {\n const kernel = this.options.kernel;\n if (!kernel) {\n return undefined;\n }\n return {\n put: (input: {\n fileName: string;\n mimeType?: string | null;\n bytes: Uint8Array;\n createdAt?: Date;\n }) => kernel.assetStore.putBytes(input),\n stat: kernel.assetStore.statRecord,\n resolveContentPath: kernel.assetStore.resolveContentPath,\n };\n };\n\n readonly putAssets = async (c: Context) => {\n const assetApi = this.getAssetApi();\n if (!assetApi) {\n return c.json(err(\"NOT_AVAILABLE\", \"ncp asset api unavailable\"), 503);\n }\n\n let formData: FormData;\n try {\n formData = await c.req.raw.formData();\n } catch {\n return c.json(err(\"INVALID_BODY\", \"invalid multipart body\"), 400);\n }\n\n const files = Array.from(formData.values()).reduce<\n Array<{\n name: string;\n type: string;\n arrayBuffer: () => Promise<ArrayBuffer>;\n }>\n >((result, value) => {\n if (typeof value !== \"string\") {\n result.push(value as {\n name: string;\n type: string;\n arrayBuffer: () => Promise<ArrayBuffer>;\n });\n }\n return result;\n }, []);\n if (files.length === 0) {\n return c.json(err(\"INVALID_BODY\", \"no files provided\"), 400);\n }\n\n const assets: UiNcpAssetView[] = [];\n for (const file of files) {\n const record = await assetApi.put({\n fileName: file.name,\n mimeType: file.type || null,\n bytes: new Uint8Array(await file.arrayBuffer()),\n });\n assets.push(toAssetView(record));\n }\n\n const payload: UiNcpAssetPutView = { assets };\n return c.json(ok(payload));\n };\n\n readonly getAssetContent = async (c: Context): Promise<Response> => {\n const assetApi = this.getAssetApi();\n if (!assetApi) {\n return c.json(err(\"NOT_AVAILABLE\", \"ncp asset api unavailable\"), 503);\n }\n\n const uri = c.req.query(\"uri\")?.trim();\n if (!uri) {\n return c.json(err(\"INVALID_URI\", \"asset uri is required\"), 400);\n }\n\n const record = await assetApi.stat(uri);\n const contentPath = assetApi.resolveContentPath(uri);\n if (!record || !contentPath) {\n return c.json(err(\"NOT_FOUND\", `asset not found: ${uri}`), 404);\n }\n\n const body = await readFile(contentPath);\n return new Response(body, {\n headers: {\n \"content-type\": resolveResponseMimeType(\n record.fileName,\n record.mimeType || \"application/octet-stream\",\n ),\n \"content-disposition\": `inline; filename*=UTF-8''${encodeContentDispositionFileName(record.fileName)}`,\n },\n });\n };\n}\n","import { parseThinkingLevel } from \"@nextclaw/core\";\nimport type { SessionPatchUpdate } from \"@nextclaw-server/shared/types/server-api.types.js\";\n\nexport function applySessionPreferencePatch(params: {\n metadata: Record<string, unknown>;\n patch: SessionPatchUpdate;\n createInvalidThinkingError: (message: string) => Error;\n}): Record<string, unknown> {\n const nextMetadata = params.metadata;\n const { patch } = params;\n\n if (Object.prototype.hasOwnProperty.call(patch, \"label\")) {\n const label = typeof patch.label === \"string\" ? patch.label.trim() : \"\";\n if (label) {\n nextMetadata.label = label;\n } else {\n delete nextMetadata.label;\n }\n }\n\n if (Object.prototype.hasOwnProperty.call(patch, \"preferredModel\")) {\n const preferredModel = typeof patch.preferredModel === \"string\" ? patch.preferredModel.trim() : \"\";\n if (preferredModel) {\n nextMetadata.preferred_model = preferredModel;\n nextMetadata.model = preferredModel;\n } else {\n delete nextMetadata.preferred_model;\n delete nextMetadata.model;\n }\n }\n\n if (Object.prototype.hasOwnProperty.call(patch, \"preferredThinking\")) {\n const preferredThinking = typeof patch.preferredThinking === \"string\" ? patch.preferredThinking.trim() : \"\";\n if (!preferredThinking) {\n delete nextMetadata.preferred_thinking;\n } else {\n const normalizedThinking = parseThinkingLevel(preferredThinking);\n if (!normalizedThinking) {\n throw params.createInvalidThinkingError(\"preferredThinking must be a supported thinking level\");\n }\n nextMetadata.preferred_thinking = normalizedThinking;\n }\n }\n\n return nextMetadata;\n}\n","import { realpath, stat } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { expandHome } from \"@nextclaw/core\";\n\nexport class SessionProjectRootValidationError extends Error {\n constructor(\n readonly code:\n | \"PROJECT_ROOT_INVALID_TYPE\"\n | \"PROJECT_ROOT_NOT_FOUND\"\n | \"PROJECT_ROOT_NOT_DIRECTORY\",\n message: string,\n ) {\n super(message);\n this.name = \"SessionProjectRootValidationError\";\n }\n}\n\nfunction resolveCandidateProjectRoot(value: string): string {\n return resolve(expandHome(value));\n}\n\nexport async function normalizeSessionProjectRoot(\n value: unknown,\n): Promise<string | null> {\n if (value == null) {\n return null;\n }\n if (typeof value !== \"string\") {\n throw new SessionProjectRootValidationError(\n \"PROJECT_ROOT_INVALID_TYPE\",\n \"projectRoot must be a string or null\",\n );\n }\n\n const trimmed = value.trim();\n if (!trimmed) {\n return null;\n }\n\n const candidate = resolveCandidateProjectRoot(trimmed);\n let canonicalPath: string;\n try {\n canonicalPath = await realpath(candidate);\n } catch {\n throw new SessionProjectRootValidationError(\n \"PROJECT_ROOT_NOT_FOUND\",\n \"projectRoot directory does not exist\",\n );\n }\n\n const projectRootStats = await stat(canonicalPath);\n if (!projectRootStats.isDirectory()) {\n throw new SessionProjectRootValidationError(\n \"PROJECT_ROOT_NOT_DIRECTORY\",\n \"projectRoot must point to a directory\",\n );\n }\n\n return canonicalPath;\n}\n\nexport function isSessionProjectRootValidationError(\n error: unknown,\n): error is SessionProjectRootValidationError {\n return error instanceof SessionProjectRootValidationError;\n}\n","export const DEFAULT_MARKETPLACE_API_BASE = \"https://marketplace-api.nextclaw.io\";\n\nexport const CLAWBAY_CHANNEL_PLUGIN_NPM_SPEC = \"@clawbay/clawbay-channel\";\nexport const MARKETPLACE_REMOTE_PAGE_SIZE = 100;\nexport const MARKETPLACE_REMOTE_MAX_PAGES = 20;\n\nexport const MARKETPLACE_ZH_COPY_BY_SLUG: Record<string, { summary: string; description?: string }> = {\n weather: {\n summary: \"NextClaw 内置技能,用于天气查询工作流。\",\n description: \"在 NextClaw 中提供快速天气查询工作流。\"\n },\n summarize: {\n summary: \"NextClaw 内置技能,用于结构化摘要。\",\n description: \"在 NextClaw 中提供文件与长文本的摘要工作流。\"\n },\n github: {\n summary: \"NextClaw 内置技能,用于 GitHub 工作流。\",\n description: \"在 NextClaw 中提供 Issue、PR 与仓库相关工作流指引。\"\n },\n tmux: {\n summary: \"NextClaw 内置技能,用于终端/Tmux 协作工作流。\",\n description: \"在 NextClaw 中提供基于 Tmux 的任务执行工作流指引。\"\n },\n gog: {\n summary: \"NextClaw 内置技能,用于图谱导向生成工作流。\",\n description: \"在 NextClaw 中提供图谱与规划导向工作流指引。\"\n },\n pdf: {\n summary: \"Anthropic 技能,用于 PDF 读取/合并/拆分/OCR 工作流。\",\n description: \"使用该技能可读取、提取、合并、拆分、旋转并对 PDF 执行 OCR 处理。\"\n },\n docx: {\n summary: \"Anthropic 技能,用于创建和编辑 Word 文档。\",\n description: \"使用该技能可创建、读取、编辑并重构 .docx 文档。\"\n },\n pptx: {\n summary: \"Anthropic 技能,用于演示文稿操作。\",\n description: \"使用该技能可创建、解析、编辑并重组 .pptx 演示文稿。\"\n },\n xlsx: {\n summary: \"Anthropic 技能,用于表格文档工作流。\",\n description: \"使用该技能可打开、编辑、清洗并转换 .xlsx 与 .csv 等表格文件。\"\n },\n bird: {\n summary: \"社区技能,用于 X/Twitter 读取/搜索/发布工作流。\",\n description: \"使用 bird CLI 在代理工作流中读取线程、搜索帖子并起草推文/回复。\"\n },\n \"cloudflare-deploy\": {\n summary: \"OpenAI 精选技能,用于在 Cloudflare 上部署应用与基础设施。\",\n description: \"使用该技能可选择 Cloudflare 产品并部署 Workers、Pages 及相关服务。\"\n },\n \"channel-extension-clawbay\": {\n summary: \"Clawbay 官方渠道扩展,用于 NextClaw 集成。\",\n description: \"通过 extension channel 机制为 NextClaw 提供 Clawbay 渠道能力。\"\n }\n};\n","const MARKETPLACE_NETWORK_RETRY_ATTEMPTS = 5;\nconst MARKETPLACE_NETWORK_RETRY_BASE_MS = 350;\n\nfunction sleepMs(ms: number): Promise<void> {\n return new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n\nfunction isRetryableMarketplaceNetworkError(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n if (error.name === \"AbortError\") {\n return false;\n }\n\n const cause = (error as Error & { cause?: unknown }).cause;\n if (cause && typeof cause === \"object\" && cause !== null && \"code\" in cause) {\n const code = (cause as { code?: unknown }).code;\n if (\n code === \"ECONNRESET\"\n || code === \"ECONNREFUSED\"\n || code === \"ETIMEDOUT\"\n || code === \"EPIPE\"\n || code === \"ENOTFOUND\"\n || code === \"EAI_AGAIN\"\n ) {\n return true;\n }\n }\n\n if (error instanceof TypeError && error.message === \"fetch failed\") {\n return true;\n }\n return false;\n}\n\nexport async function runWithMarketplaceNetworkRetry<T>(action: () => Promise<T>): Promise<T> {\n let lastError: unknown;\n for (let attempt = 1; attempt <= MARKETPLACE_NETWORK_RETRY_ATTEMPTS; attempt += 1) {\n try {\n return await action();\n } catch (error) {\n lastError = error;\n if (attempt === MARKETPLACE_NETWORK_RETRY_ATTEMPTS || !isRetryableMarketplaceNetworkError(error)) {\n throw error;\n }\n await sleepMs(MARKETPLACE_NETWORK_RETRY_BASE_MS * 2 ** (attempt - 1));\n }\n }\n throw lastError;\n}\n","import type { MarketplaceItemView, MarketplaceListView } from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport { readErrorMessage } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport type { UiRouterOptions } from \"@nextclaw-server/app/types/router-options.types.js\";\nimport {\n DEFAULT_MARKETPLACE_API_BASE,\n MARKETPLACE_REMOTE_MAX_PAGES,\n MARKETPLACE_REMOTE_PAGE_SIZE,\n MARKETPLACE_ZH_COPY_BY_SLUG\n} from \"@nextclaw-server/features/marketplace/index.js\";\nimport { runWithMarketplaceNetworkRetry } from \"./marketplace-network-retry.utils.js\";\n\nconst MARKETPLACE_FETCH_TIMEOUT_MS = 12_000;\n\nexport function normalizeMarketplaceBaseUrl(options: UiRouterOptions): string {\n const configured = options.marketplace?.apiBaseUrl?.trim();\n if (!configured) {\n return DEFAULT_MARKETPLACE_API_BASE;\n }\n return configured.replace(/\\/$/, \"\");\n}\n\nexport function toMarketplaceUrl(baseUrl: string, path: string, query: Record<string, string | undefined> = {}): string {\n const url = new URL(path, `${baseUrl.replace(/\\/$/, \"\")}/`);\n for (const [key, value] of Object.entries(query)) {\n if (typeof value === \"string\" && value.length > 0) {\n url.searchParams.set(key, value);\n }\n }\n return url.toString();\n}\n\nexport async function fetchMarketplaceData<T>(params: {\n baseUrl: string;\n path: string;\n query?: Record<string, string | undefined>;\n}): Promise<{ ok: true; data: T } | { ok: false; status: number; message: string }> {\n const endpoint = toMarketplaceUrl(params.baseUrl, params.path, params.query);\n let response: Response;\n try {\n response = await runWithMarketplaceNetworkRetry(() =>\n fetch(endpoint, {\n method: \"GET\",\n headers: {\n Accept: \"application/json\"\n },\n signal: AbortSignal.timeout(MARKETPLACE_FETCH_TIMEOUT_MS)\n })\n );\n } catch (error) {\n return {\n ok: false,\n status: 503,\n message: error instanceof Error ? error.message : String(error)\n };\n }\n\n let payload: unknown = null;\n try {\n payload = await response.json();\n } catch {\n if (!response.ok) {\n return {\n ok: false,\n status: response.status,\n message: `marketplace request failed (${response.status})`\n };\n }\n return {\n ok: false,\n status: 502,\n message: \"invalid marketplace response\"\n };\n }\n\n if (!response.ok) {\n return {\n ok: false,\n status: response.status,\n message: readErrorMessage(payload, `marketplace request failed (${response.status})`)\n };\n }\n\n if (!payload || typeof payload !== \"object\" || !(\"ok\" in payload)) {\n return {\n ok: false,\n status: 502,\n message: \"invalid marketplace response\"\n };\n }\n\n const typed = payload as {\n ok?: boolean;\n data?: T;\n error?: {\n message?: string;\n };\n };\n\n if (!typed.ok) {\n return {\n ok: false,\n status: 502,\n message: readErrorMessage(payload, \"marketplace response returned error\")\n };\n }\n\n return {\n ok: true,\n data: typed.data as T\n };\n}\n\nfunction sanitizeMarketplaceItem<T extends Record<string, unknown>>(item: T): T {\n const next = { ...item } as T;\n delete (next as { sourceType?: unknown }).sourceType;\n return next;\n}\n\nfunction readLocalizedMap(value: unknown): Record<string, string> {\n const localized: Record<string, string> = {};\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return localized;\n }\n\n for (const [key, entry] of Object.entries(value as Record<string, unknown>)) {\n if (typeof entry !== \"string\" || entry.trim().length === 0) {\n continue;\n }\n localized[key] = entry.trim();\n }\n return localized;\n}\n\nfunction normalizeLocaleTag(value: string): string {\n return value.trim().toLowerCase().replace(/_/g, \"-\");\n}\n\nfunction pickLocaleFamilyValue(localized: Record<string, string>, localeFamily: string): string | undefined {\n const normalizedFamily = normalizeLocaleTag(localeFamily).split(\"-\")[0];\n if (!normalizedFamily) {\n return undefined;\n }\n\n let familyMatch: string | undefined;\n for (const [locale, text] of Object.entries(localized)) {\n const normalizedLocale = normalizeLocaleTag(locale);\n if (!normalizedLocale) {\n continue;\n }\n if (normalizedLocale === normalizedFamily) {\n return text;\n }\n if (!familyMatch && normalizedLocale.startsWith(`${normalizedFamily}-`)) {\n familyMatch = text;\n }\n }\n\n return familyMatch;\n}\n\nfunction normalizeLocalizedTextMap(primaryText: string, localized: unknown, zhFallback?: string): Record<string, string> {\n const next = readLocalizedMap(localized);\n if (!next.en) {\n next.en = pickLocaleFamilyValue(next, \"en\") ?? primaryText;\n }\n if (!next.zh) {\n next.zh = pickLocaleFamilyValue(next, \"zh\")\n ?? (zhFallback && zhFallback.trim().length > 0 ? zhFallback.trim() : next.en);\n }\n return next;\n}\n\nexport function normalizeMarketplaceItemForUi<T extends MarketplaceItemView | MarketplaceListView[\"items\"][number]>(item: T): T {\n const zhCopy = MARKETPLACE_ZH_COPY_BY_SLUG[item.slug];\n const next = {\n ...item,\n summaryI18n: normalizeLocalizedTextMap(item.summary, (item as { summaryI18n?: unknown }).summaryI18n, zhCopy?.summary)\n } as T & {\n summaryI18n: Record<string, string>;\n descriptionI18n?: Record<string, string>;\n };\n\n if (\"description\" in item && typeof item.description === \"string\" && item.description.trim().length > 0) {\n next.descriptionI18n = normalizeLocalizedTextMap(\n item.description,\n (item as { descriptionI18n?: unknown }).descriptionI18n,\n zhCopy?.description\n );\n }\n\n return next as T;\n}\n\nexport function toPositiveInt(raw: string | undefined, fallback: number): number {\n if (!raw) {\n return fallback;\n }\n const parsed = Number.parseInt(raw, 10);\n if (!Number.isFinite(parsed) || parsed <= 0) {\n return fallback;\n }\n return parsed;\n}\n\nexport async function fetchAllMarketplaceItems(params: {\n baseUrl: string;\n path: string;\n query?: Record<string, string | undefined>;\n}): Promise<\n | { ok: true; data: { sort: MarketplaceListView[\"sort\"]; query?: string; items: MarketplaceListView[\"items\"] } }\n | { ok: false; status: number; message: string }\n> {\n const items: MarketplaceListView[\"items\"] = [];\n let sort: MarketplaceListView[\"sort\"] = \"relevance\";\n let query: MarketplaceListView[\"query\"];\n\n for (let page = 1; page <= MARKETPLACE_REMOTE_MAX_PAGES; page += 1) {\n const result = await fetchMarketplaceData<MarketplaceListView>({\n baseUrl: params.baseUrl,\n path: params.path,\n query: {\n ...params.query,\n page: String(page),\n pageSize: String(MARKETPLACE_REMOTE_PAGE_SIZE)\n }\n });\n\n if (!result.ok) {\n return result;\n }\n\n const pageItems = Array.isArray(result.data.items) ? result.data.items : [];\n if (pageItems.length === 0) {\n break;\n }\n\n sort = result.data.sort;\n query = result.data.query;\n items.push(...pageItems);\n\n const pageSize =\n typeof result.data.pageSize === \"number\" && Number.isFinite(result.data.pageSize) && result.data.pageSize > 0\n ? result.data.pageSize\n : MARKETPLACE_REMOTE_PAGE_SIZE;\n if (pageItems.length < pageSize) {\n break;\n }\n }\n\n return {\n ok: true,\n data: {\n sort,\n ...(typeof query === \"string\" ? { query } : {}),\n items\n }\n };\n}\n\nexport async function fetchAllSkillMarketplaceItems(params: {\n baseUrl: string;\n query?: Record<string, string | undefined>;\n}): Promise<\n | { ok: true; data: { sort: MarketplaceListView[\"sort\"]; query?: string; items: MarketplaceListView[\"items\"] } }\n | { ok: false; status: number; message: string }\n> {\n return fetchAllMarketplaceItems({\n baseUrl: params.baseUrl,\n path: \"/api/v1/skills/items\",\n query: params.query\n });\n}\n\nexport async function fetchAllMcpMarketplaceItems(params: {\n baseUrl: string;\n query?: Record<string, string | undefined>;\n}): Promise<\n | { ok: true; data: { sort: MarketplaceListView[\"sort\"]; query?: string; items: MarketplaceListView[\"items\"] } }\n | { ok: false; status: number; message: string }\n> {\n return fetchAllMarketplaceItems({\n baseUrl: params.baseUrl,\n path: \"/api/v1/mcp/items\",\n query: params.query\n });\n}\n\nexport function sanitizeMarketplaceListItems(items: MarketplaceListView[\"items\"]): MarketplaceListView[\"items\"] {\n return items.map((item) => sanitizeMarketplaceItem(item));\n}\n\nexport function sanitizeMarketplaceItemView(item: MarketplaceItemView): MarketplaceItemView {\n return sanitizeMarketplaceItem(item);\n}\n","import { McpInstalledViewService } from \"@nextclaw/mcp\";\nimport type { Context } from \"hono\";\nimport type {\n MarketplaceInstalledView,\n MarketplaceItemView,\n MarketplaceMcpContentView,\n MarketplaceMcpDoctorResult,\n MarketplaceMcpInstallRequest,\n MarketplaceMcpInstallResult,\n MarketplaceMcpInstallSpec,\n MarketplaceMcpManageRequest,\n MarketplaceMcpManageResult,\n MarketplaceRecommendationView\n} from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport { loadConfigOrDefault } from \"@nextclaw-server/features/config/index.js\";\nimport { err, ok, readJson } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport type { UiRouterOptions } from \"@nextclaw-server/app/types/router-options.types.js\";\nimport { emitConfigUpdated } from \"@nextclaw-server/shared/utils/app-events.utils.js\";\nimport {\n fetchAllMcpMarketplaceItems,\n fetchMarketplaceData,\n normalizeMarketplaceItemForUi,\n sanitizeMarketplaceItemView,\n sanitizeMarketplaceListItems,\n toPositiveInt\n} from \"@nextclaw-server/features/marketplace/utils/marketplace-catalog.utils.js\";\n\nexport class McpMarketplaceController {\n constructor(\n private readonly options: UiRouterOptions,\n private readonly marketplaceBaseUrl: string\n ) {}\n\n readonly getInstalled = (c: Context) => {\n const service = new McpInstalledViewService({\n getConfig: () => loadConfigOrDefault(this.options.configPath)\n });\n const records = service.listInstalled().map((record) => ({\n type: \"mcp\" as const,\n id: record.name,\n spec: record.catalogSlug ?? record.name,\n label: record.displayName ?? record.name,\n enabled: record.enabled,\n runtimeStatus: record.enabled ? \"enabled\" : \"disabled\",\n transport: record.transport,\n scope: record.scope,\n catalogSlug: record.catalogSlug,\n vendor: record.vendor,\n docsUrl: record.docsUrl,\n homepage: record.homepage,\n trustLevel: record.trustLevel,\n source: record.source,\n installedAt: record.installedAt,\n toolCount: record.toolCount,\n accessible: record.accessible,\n lastReadyAt: record.lastReadyAt,\n lastDoctorAt: record.lastReadyAt,\n lastError: record.lastError\n }));\n\n return c.json(ok({\n type: \"mcp\",\n total: records.length,\n specs: records.map((record) => record.spec),\n records\n } satisfies MarketplaceInstalledView));\n };\n\n readonly listItems = async (c: Context) => {\n const query = c.req.query();\n const result = await fetchAllMcpMarketplaceItems({\n baseUrl: this.marketplaceBaseUrl,\n query: {\n q: query.q,\n tag: query.tag,\n sort: query.sort,\n page: query.page,\n pageSize: query.pageSize\n }\n });\n\n if (!result.ok) {\n return c.json(err(\"MARKETPLACE_UNAVAILABLE\", result.message), result.status as 500);\n }\n\n const items = sanitizeMarketplaceListItems(result.data.items).map((item) => normalizeMarketplaceItemForUi(item));\n const pageSize = Math.min(100, toPositiveInt(query.pageSize, 20));\n const requestedPage = toPositiveInt(query.page, 1);\n const totalPages = items.length === 0 ? 0 : Math.ceil(items.length / pageSize);\n const currentPage = totalPages === 0 ? 1 : Math.min(requestedPage, totalPages);\n\n return c.json(ok({\n total: items.length,\n page: currentPage,\n pageSize,\n totalPages,\n sort: result.data.sort,\n query: result.data.query,\n items: items.slice((currentPage - 1) * pageSize, currentPage * pageSize)\n }));\n };\n\n readonly getItem = async (c: Context) => {\n const slug = encodeURIComponent(c.req.param(\"slug\"));\n const result = await fetchMarketplaceData<MarketplaceItemView>({\n baseUrl: this.marketplaceBaseUrl,\n path: `/api/v1/mcp/items/${slug}`\n });\n if (!result.ok) {\n return c.json(err(\"MARKETPLACE_UNAVAILABLE\", result.message), result.status as 500);\n }\n return c.json(ok(normalizeMarketplaceItemForUi(sanitizeMarketplaceItemView(result.data))));\n };\n\n readonly getItemContent = async (c: Context) => {\n const slug = encodeURIComponent(c.req.param(\"slug\"));\n const result = await fetchMarketplaceData<MarketplaceMcpContentView>({\n baseUrl: this.marketplaceBaseUrl,\n path: `/api/v1/mcp/items/${slug}/content`\n });\n if (!result.ok) {\n return c.json(err(\"MARKETPLACE_UNAVAILABLE\", result.message), result.status as 500);\n }\n return c.json(ok(result.data));\n };\n\n readonly install = async (c: Context) => {\n const body = await readJson<MarketplaceMcpInstallRequest>(c.req.raw);\n if (!body.ok || !body.data || typeof body.data !== \"object\") {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n if (body.data.type && body.data.type !== \"mcp\") {\n return c.json(err(\"INVALID_BODY\", \"body.type does not match route type\"), 400);\n }\n\n const slug = typeof body.data.spec === \"string\" ? body.data.spec.trim() : \"\";\n if (!slug) {\n return c.json(err(\"INVALID_BODY\", \"non-empty spec is required\"), 400);\n }\n\n const installer = this.options.marketplace?.installer;\n if (!installer?.installMcp) {\n return c.json(err(\"NOT_AVAILABLE\", \"mcp installer is not configured\"), 503);\n }\n\n const itemResult = await fetchMarketplaceData<MarketplaceItemView>({\n baseUrl: this.marketplaceBaseUrl,\n path: `/api/v1/mcp/items/${encodeURIComponent(slug)}`\n });\n if (!itemResult.ok) {\n return c.json(err(\"MARKETPLACE_UNAVAILABLE\", itemResult.message), itemResult.status as 500);\n }\n\n const template = itemResult.data.install as MarketplaceMcpInstallSpec;\n if (template.kind !== \"template\") {\n return c.json(err(\"MARKETPLACE_CONTRACT_MISMATCH\", `unsupported mcp install kind: ${template.kind}`), 502);\n }\n\n try {\n const result = await installer.installMcp({\n ...body.data,\n template\n });\n emitConfigUpdated(this.options, \"mcp\");\n return c.json(ok({\n type: \"mcp\",\n spec: slug,\n name: result.name,\n message: result.message,\n output: result.output\n } satisfies MarketplaceMcpInstallResult));\n } catch (error) {\n return c.json(err(\"INSTALL_FAILED\", error instanceof Error ? error.message : String(error)), 400);\n }\n };\n\n readonly manage = async (c: Context) => {\n const body = await readJson<MarketplaceMcpManageRequest>(c.req.raw);\n if (!body.ok || !body.data || typeof body.data !== \"object\") {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n if (body.data.type && body.data.type !== \"mcp\") {\n return c.json(err(\"INVALID_BODY\", \"body.type does not match route type\"), 400);\n }\n\n const target = typeof body.data.id === \"string\" && body.data.id.trim().length > 0\n ? body.data.id.trim()\n : typeof body.data.spec === \"string\" && body.data.spec.trim().length > 0\n ? body.data.spec.trim()\n : \"\";\n if (!target) {\n return c.json(err(\"INVALID_BODY\", \"non-empty id/spec is required\"), 400);\n }\n\n const installer = this.options.marketplace?.installer;\n if (!installer) {\n return c.json(err(\"NOT_AVAILABLE\", \"marketplace installer is not configured\"), 503);\n }\n\n try {\n const action = body.data.action;\n const result = action === \"enable\"\n ? await installer.enableMcp?.(target)\n : action === \"disable\"\n ? await installer.disableMcp?.(target)\n : await installer.removeMcp?.(target);\n\n if (!result) {\n return c.json(err(\"NOT_AVAILABLE\", `mcp ${action} is not configured`), 503);\n }\n\n emitConfigUpdated(this.options, \"mcp\");\n return c.json(ok({\n type: \"mcp\",\n action,\n id: target,\n message: result.message,\n output: result.output\n } satisfies MarketplaceMcpManageResult));\n } catch (error) {\n return c.json(err(\"MANAGE_FAILED\", error instanceof Error ? error.message : String(error)), 400);\n }\n };\n\n readonly doctor = async (c: Context) => {\n const body = await readJson<{ name?: string; id?: string; spec?: string }>(c.req.raw);\n if (!body.ok || !body.data || typeof body.data !== \"object\") {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n const target = typeof body.data.name === \"string\" && body.data.name.trim().length > 0\n ? body.data.name.trim()\n : typeof body.data.id === \"string\" && body.data.id.trim().length > 0\n ? body.data.id.trim()\n : typeof body.data.spec === \"string\" && body.data.spec.trim().length > 0\n ? body.data.spec.trim()\n : \"\";\n if (!target) {\n return c.json(err(\"INVALID_BODY\", \"name/id/spec is required\"), 400);\n }\n\n const installer = this.options.marketplace?.installer;\n if (!installer?.doctorMcp) {\n return c.json(err(\"NOT_AVAILABLE\", \"mcp doctor is not configured\"), 503);\n }\n\n try {\n const result = await installer.doctorMcp(target);\n return c.json(ok(result satisfies MarketplaceMcpDoctorResult));\n } catch (error) {\n return c.json(err(\"DOCTOR_FAILED\", error instanceof Error ? error.message : String(error)), 400);\n }\n };\n\n readonly getRecommendations = async (c: Context) => {\n const query = c.req.query();\n const result = await fetchMarketplaceData<MarketplaceRecommendationView>({\n baseUrl: this.marketplaceBaseUrl,\n path: \"/api/v1/mcp/recommendations\",\n query: {\n scene: query.scene,\n limit: query.limit\n }\n });\n if (!result.ok) {\n return c.json(err(\"MARKETPLACE_UNAVAILABLE\", result.message), result.status as 500);\n }\n return c.json(ok({\n ...result.data,\n items: sanitizeMarketplaceListItems(result.data.items).map((item) => normalizeMarketplaceItemForUi(item))\n }));\n };\n}\n","import * as NextclawCore from \"@nextclaw/core\";\nimport { loadConfigOrDefault } from \"@nextclaw-server/features/config/index.js\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport type {\n MarketplaceInstalledRecord,\n MarketplaceInstalledView,\n MarketplaceItemView,\n MarketplaceListView\n} from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport { readNonEmptyString } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport type { SkillsLoaderConstructor, SkillsLoaderInstance, UiRouterOptions } from \"@nextclaw-server/app/types/router-options.types.js\";\nimport { MARKETPLACE_ZH_COPY_BY_SLUG } from \"@nextclaw-server/features/marketplace/index.js\";\n\nconst getWorkspacePathFromConfig = NextclawCore.getWorkspacePathFromConfig;\nconst MARKETPLACE_INSTALL_STATE_FILE = \".nextclaw-install.json\";\n\nfunction createSkillsLoader(workspace: string): SkillsLoaderInstance | null {\n const ctor = (NextclawCore as { SkillsLoader?: SkillsLoaderConstructor }).SkillsLoader;\n if (!ctor) {\n return null;\n }\n return new ctor(workspace);\n}\n\nexport function collectInstalledSkillRecords(options: UiRouterOptions): {\n records: MarketplaceInstalledRecord[];\n specs: string[];\n} {\n const config = loadConfigOrDefault(options.configPath);\n const workspacePath = getWorkspacePathFromConfig(config);\n const skillsLoader = createSkillsLoader(workspacePath);\n const availableSkillSet = new Set((skillsLoader?.listSkills(true) ?? []).map((skill) => skill.name));\n const listedSkills = skillsLoader?.listSkills(false) ?? [];\n\n const records = listedSkills\n .map((skill) => {\n const enabled = availableSkillSet.has(skill.name);\n const metadata = skillsLoader?.getSkillMetadata?.(skill);\n const description = readNonEmptyString(metadata?.description);\n const descriptionZh =\n readNonEmptyString(metadata?.description_zh) ??\n readNonEmptyString(metadata?.descriptionZh) ??\n readNonEmptyString(MARKETPLACE_ZH_COPY_BY_SLUG[skill.name]?.description);\n const marketplaceState = readMarketplaceSkillInstallState(dirname(skill.path));\n const origin = marketplaceState ? \"marketplace\" : undefined;\n const catalogSlug = marketplaceState?.slug;\n const installedAt = marketplaceState?.installedAt;\n return {\n type: \"skill\",\n id: skill.name,\n spec: skill.name,\n label: skill.name,\n description,\n descriptionZh,\n source: skill.source,\n origin,\n catalogSlug,\n installedAt,\n enabled,\n runtimeStatus: enabled ? \"enabled\" : \"disabled\"\n } satisfies MarketplaceInstalledRecord;\n })\n .sort((left, right) => left.spec.localeCompare(right.spec));\n\n return {\n specs: records.map((record) => record.spec),\n records\n };\n}\n\nfunction readMarketplaceSkillInstallState(destinationDir: string): {\n slug: string;\n installedAt?: string;\n} | null {\n const statePath = join(destinationDir, MARKETPLACE_INSTALL_STATE_FILE);\n if (!existsSync(statePath)) {\n return null;\n }\n\n try {\n const parsed = JSON.parse(readFileSync(statePath, \"utf8\")) as {\n schemaVersion?: unknown;\n type?: unknown;\n source?: unknown;\n slug?: unknown;\n installedAt?: unknown;\n };\n if (\n parsed.schemaVersion !== 1\n || parsed.type !== \"skill\"\n || parsed.source !== \"marketplace\"\n || typeof parsed.slug !== \"string\"\n ) {\n return null;\n }\n\n return {\n slug: parsed.slug,\n installedAt: typeof parsed.installedAt === \"string\" ? parsed.installedAt : undefined\n };\n } catch {\n return null;\n }\n}\n\nexport function collectSkillMarketplaceInstalledView(options: UiRouterOptions): MarketplaceInstalledView {\n const installed = collectInstalledSkillRecords(options);\n return {\n type: \"skill\",\n total: installed.records.length,\n specs: installed.specs,\n records: installed.records\n };\n}\n\nexport function collectKnownSkillNames(options: UiRouterOptions): Set<string> {\n const config = loadConfigOrDefault(options.configPath);\n const loader = createSkillsLoader(getWorkspacePathFromConfig(config));\n return new Set((loader?.listSkills(false) ?? []).map((skill) => skill.name));\n}\n\nexport function isSupportedMarketplaceSkillItem(\n item: MarketplaceItemView | MarketplaceListView[\"items\"][number],\n knownSkillNames: Set<string>\n): boolean {\n if (item.type !== \"skill\") {\n return false;\n }\n\n if (item.install.kind === \"marketplace\") {\n return true;\n }\n\n return item.install.kind === \"builtin\" && knownSkillNames.has(item.install.spec);\n}\n\nexport function findUnsupportedSkillInstallKind(\n items: Array<MarketplaceItemView | MarketplaceListView[\"items\"][number]>\n): string | null {\n for (const item of items) {\n if (item.type !== \"skill\") {\n continue;\n }\n const kind = item.install.kind as string;\n if (kind !== \"builtin\" && kind !== \"marketplace\") {\n return kind;\n }\n }\n return null;\n}\n","import type { Context } from \"hono\";\nimport type {\n MarketplaceItemView,\n MarketplaceListView,\n MarketplaceRecommendationView,\n MarketplaceScenesView,\n MarketplaceSkillContentView,\n MarketplaceSkillInstallRequest,\n MarketplaceSkillInstallResult,\n MarketplaceSkillManageRequest,\n MarketplaceSkillManageResult\n} from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport { err, ok, readJson } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport type { UiRouterOptions } from \"@nextclaw-server/app/types/router-options.types.js\";\nimport { emitConfigUpdated } from \"@nextclaw-server/shared/utils/app-events.utils.js\";\nimport {\n fetchMarketplaceData,\n normalizeMarketplaceItemForUi,\n sanitizeMarketplaceItemView,\n sanitizeMarketplaceListItems\n} from \"@nextclaw-server/features/marketplace/utils/marketplace-catalog.utils.js\";\nimport {\n collectKnownSkillNames,\n collectSkillMarketplaceInstalledView,\n findUnsupportedSkillInstallKind,\n isSupportedMarketplaceSkillItem\n} from \"@nextclaw-server/features/marketplace/utils/marketplace-installed.utils.js\";\n\ntype SupportedSkillMarketplaceListResult =\n | { ok: true; data: MarketplaceListView }\n | { ok: false; status: number; code: \"MARKETPLACE_UNAVAILABLE\" | \"MARKETPLACE_CONTRACT_MISMATCH\"; message: string };\n\nasync function installMarketplaceSkill(params: {\n options: UiRouterOptions;\n body: MarketplaceSkillInstallRequest;\n}): Promise<MarketplaceSkillInstallResult> {\n const { body, options } = params;\n const spec = typeof body.spec === \"string\" ? body.spec.trim() : \"\";\n if (!spec) {\n throw new Error(\"INVALID_BODY:non-empty spec is required\");\n }\n\n const installer = options.marketplace?.installer;\n if (!installer) {\n throw new Error(\"NOT_AVAILABLE:marketplace installer is not configured\");\n }\n if (!installer.installSkill) {\n throw new Error(\"NOT_AVAILABLE:skill installer is not configured\");\n }\n\n const result = await installer.installSkill({\n slug: spec,\n kind: body.kind,\n skill: body.skill,\n installPath: body.installPath,\n force: body.force\n });\n\n emitConfigUpdated(options, \"skills\");\n return {\n type: \"skill\",\n spec,\n message: result.message,\n output: result.output\n };\n}\n\nasync function manageMarketplaceSkill(params: {\n options: UiRouterOptions;\n body: MarketplaceSkillManageRequest;\n}): Promise<MarketplaceSkillManageResult> {\n const { body, options } = params;\n const action = body.action;\n const targetId = typeof body.id === \"string\" && body.id.trim().length > 0\n ? body.id.trim()\n : typeof body.spec === \"string\" && body.spec.trim().length > 0\n ? body.spec.trim()\n : \"\";\n\n if ((action !== \"update\" && action !== \"uninstall\") || !targetId) {\n throw new Error(\"INVALID_BODY:skill manage requires update/uninstall action and non-empty id/spec\");\n }\n\n const installer = options.marketplace?.installer;\n if (!installer) {\n throw new Error(\"NOT_AVAILABLE:marketplace installer is not configured\");\n }\n\n if (action === \"update\") {\n if (!installer.updateSkill) {\n throw new Error(\"NOT_AVAILABLE:skill update is not configured\");\n }\n\n const result = await installer.updateSkill({\n slug: targetId,\n force: body.force\n });\n emitConfigUpdated(options, \"skills\");\n\n return {\n type: \"skill\",\n action,\n id: targetId,\n message: result.message,\n output: result.output\n };\n }\n\n if (!installer.uninstallSkill) {\n throw new Error(\"NOT_AVAILABLE:skill uninstall is not configured\");\n }\n\n const result = await installer.uninstallSkill(targetId);\n emitConfigUpdated(options, \"skills\");\n\n return {\n type: \"skill\",\n action,\n id: targetId,\n message: result.message,\n output: result.output\n };\n}\n\nexport class SkillMarketplaceController {\n constructor(\n private readonly options: UiRouterOptions,\n private readonly marketplaceBaseUrl: string\n ) {}\n\n readonly getInstalled = (c: Context) => {\n return c.json(ok(collectSkillMarketplaceInstalledView(this.options)));\n };\n\n private readonly normalizeSupportedListData = (\n data: MarketplaceListView\n ): SupportedSkillMarketplaceListResult => {\n const normalizedItems = sanitizeMarketplaceListItems(data.items)\n .map((item) => normalizeMarketplaceItemForUi(item));\n const unsupportedKind = findUnsupportedSkillInstallKind(normalizedItems);\n if (unsupportedKind) {\n return {\n ok: false,\n code: \"MARKETPLACE_CONTRACT_MISMATCH\",\n status: 502,\n message: `unsupported skill install kind from marketplace api: ${unsupportedKind}`\n };\n }\n\n const knownSkillNames = collectKnownSkillNames(this.options);\n return {\n ok: true,\n data: {\n ...data,\n items: normalizedItems.filter((item) => isSupportedMarketplaceSkillItem(item, knownSkillNames))\n }\n };\n };\n\n private readonly loadSupportedListPage = async (\n query: Record<string, string | undefined>\n ): Promise<SupportedSkillMarketplaceListResult> => {\n const result = await fetchMarketplaceData<MarketplaceListView>({\n baseUrl: this.marketplaceBaseUrl,\n path: \"/api/v1/skills/items\",\n query\n });\n if (!result.ok) {\n return {\n ...result,\n code: \"MARKETPLACE_UNAVAILABLE\"\n };\n }\n return this.normalizeSupportedListData(result.data);\n };\n\n readonly listScenes = async (c: Context) => {\n const result = await fetchMarketplaceData<MarketplaceScenesView>({\n baseUrl: this.marketplaceBaseUrl,\n path: \"/api/v1/skills/scenes\"\n });\n if (!result.ok) {\n return c.json(err(\"MARKETPLACE_UNAVAILABLE\", result.message), result.status as 500);\n }\n\n return c.json(ok<MarketplaceScenesView>(result.data));\n };\n\n readonly listItems = async (c: Context) => {\n const query = c.req.query();\n const result = await this.loadSupportedListPage({\n q: query.q,\n scene: query.scene,\n tag: query.tag,\n sort: query.sort,\n page: query.page,\n pageSize: query.pageSize\n });\n\n if (!result.ok) {\n return c.json(err(result.code, result.message), result.status as 500);\n }\n\n return c.json(ok(result.data));\n };\n\n readonly getItem = async (c: Context) => {\n const slug = encodeURIComponent(c.req.param(\"slug\"));\n const result = await fetchMarketplaceData<MarketplaceItemView>({\n baseUrl: this.marketplaceBaseUrl,\n path: `/api/v1/skills/items/${slug}`\n });\n\n if (!result.ok) {\n return c.json(err(\"MARKETPLACE_UNAVAILABLE\", result.message), result.status as 500);\n }\n\n const knownSkillNames = collectKnownSkillNames(this.options);\n const sanitized = normalizeMarketplaceItemForUi(sanitizeMarketplaceItemView(result.data));\n const unsupportedKind = findUnsupportedSkillInstallKind([sanitized]);\n if (unsupportedKind) {\n return c.json(\n err(\"MARKETPLACE_CONTRACT_MISMATCH\", `unsupported skill install kind from marketplace api: ${unsupportedKind}`),\n 502\n );\n }\n if (!isSupportedMarketplaceSkillItem(sanitized, knownSkillNames)) {\n return c.json(err(\"NOT_FOUND\", \"marketplace item not supported by nextclaw\"), 404);\n }\n\n return c.json(ok(sanitized));\n };\n\n readonly getItemContent = async (c: Context) => {\n const slug = encodeURIComponent(c.req.param(\"slug\"));\n const result = await fetchMarketplaceData<MarketplaceItemView>({\n baseUrl: this.marketplaceBaseUrl,\n path: `/api/v1/skills/items/${slug}`\n });\n\n if (!result.ok) {\n return c.json(err(\"MARKETPLACE_UNAVAILABLE\", result.message), result.status as 500);\n }\n\n const knownSkillNames = collectKnownSkillNames(this.options);\n const sanitized = normalizeMarketplaceItemForUi(sanitizeMarketplaceItemView(result.data));\n const unsupportedKind = findUnsupportedSkillInstallKind([sanitized]);\n if (unsupportedKind) {\n return c.json(\n err(\"MARKETPLACE_CONTRACT_MISMATCH\", `unsupported skill install kind from marketplace api: ${unsupportedKind}`),\n 502\n );\n }\n if (!isSupportedMarketplaceSkillItem(sanitized, knownSkillNames)) {\n return c.json(err(\"NOT_FOUND\", \"marketplace item not supported by nextclaw\"), 404);\n }\n\n const contentResult = await fetchMarketplaceData<MarketplaceSkillContentView>({\n baseUrl: this.marketplaceBaseUrl,\n path: `/api/v1/skills/items/${slug}/content`\n });\n if (!contentResult.ok) {\n return c.json(err(\"MARKETPLACE_UNAVAILABLE\", contentResult.message), contentResult.status as 500);\n }\n\n return c.json(ok(contentResult.data));\n };\n\n readonly install = async (c: Context) => {\n const body = await readJson<MarketplaceSkillInstallRequest>(c.req.raw);\n if (!body.ok || !body.data || typeof body.data !== \"object\") {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n if (body.data.type && body.data.type !== \"skill\") {\n return c.json(err(\"INVALID_BODY\", \"body.type does not match route type\"), 400);\n }\n\n try {\n const payload = await installMarketplaceSkill({\n options: this.options,\n body: body.data\n });\n return c.json(ok(payload));\n } catch (error) {\n const message = String(error);\n if (message.startsWith(\"INVALID_BODY:\")) {\n return c.json(err(\"INVALID_BODY\", message.slice(\"INVALID_BODY:\".length)), 400);\n }\n if (message.startsWith(\"NOT_AVAILABLE:\")) {\n return c.json(err(\"NOT_AVAILABLE\", message.slice(\"NOT_AVAILABLE:\".length)), 503);\n }\n return c.json(err(\"INSTALL_FAILED\", message), 400);\n }\n };\n\n readonly manage = async (c: Context) => {\n const body = await readJson<MarketplaceSkillManageRequest>(c.req.raw);\n if (!body.ok || !body.data || typeof body.data !== \"object\") {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n if (body.data.type && body.data.type !== \"skill\") {\n return c.json(err(\"INVALID_BODY\", \"body.type does not match route type\"), 400);\n }\n\n try {\n const payload = await manageMarketplaceSkill({\n options: this.options,\n body: body.data\n });\n return c.json(ok(payload));\n } catch (error) {\n const message = String(error);\n if (message.startsWith(\"INVALID_BODY:\")) {\n return c.json(err(\"INVALID_BODY\", message.slice(\"INVALID_BODY:\".length)), 400);\n }\n if (message.startsWith(\"NOT_AVAILABLE:\")) {\n return c.json(err(\"NOT_AVAILABLE\", message.slice(\"NOT_AVAILABLE:\".length)), 503);\n }\n return c.json(err(\"MANAGE_FAILED\", message), 400);\n }\n };\n\n readonly getRecommendations = async (c: Context) => {\n const query = c.req.query();\n const result = await fetchMarketplaceData<MarketplaceRecommendationView>({\n baseUrl: this.marketplaceBaseUrl,\n path: \"/api/v1/skills/recommendations\",\n query: {\n scene: query.scene,\n limit: query.limit\n }\n });\n\n if (!result.ok) {\n return c.json(err(\"MARKETPLACE_UNAVAILABLE\", result.message), result.status as 500);\n }\n\n const knownSkillNames = collectKnownSkillNames(this.options);\n const filteredItems = sanitizeMarketplaceListItems(result.data.items)\n .map((item) => normalizeMarketplaceItemForUi(item))\n .filter((item) => isSupportedMarketplaceSkillItem(item, knownSkillNames));\n\n return c.json(ok({\n ...result.data,\n total: filteredItems.length,\n items: filteredItems\n }));\n };\n}\n","import type { Hono } from \"hono\";\nimport type { McpMarketplaceController } from \"@nextclaw-server/features/marketplace/controllers/mcp-marketplace.controller.js\";\nimport type { SkillMarketplaceController } from \"@nextclaw-server/features/marketplace/controllers/skill-marketplace.controller.js\";\n\nexport function mountMarketplaceRoutes(\n app: Hono,\n controllers: {\n skill: SkillMarketplaceController;\n mcp: McpMarketplaceController;\n }\n): void {\n app.get(\"/api/marketplace/skills/installed\", controllers.skill.getInstalled);\n app.get(\"/api/marketplace/skills/scenes\", controllers.skill.listScenes);\n app.get(\"/api/marketplace/skills/items\", controllers.skill.listItems);\n app.get(\"/api/marketplace/skills/items/:slug\", controllers.skill.getItem);\n app.get(\"/api/marketplace/skills/items/:slug/content\", controllers.skill.getItemContent);\n app.post(\"/api/marketplace/skills/install\", controllers.skill.install);\n app.post(\"/api/marketplace/skills/manage\", controllers.skill.manage);\n app.get(\"/api/marketplace/skills/recommendations\", controllers.skill.getRecommendations);\n\n app.get(\"/api/marketplace/mcp/installed\", controllers.mcp.getInstalled);\n app.get(\"/api/marketplace/mcp/items\", controllers.mcp.listItems);\n app.get(\"/api/marketplace/mcp/items/:slug\", controllers.mcp.getItem);\n app.get(\"/api/marketplace/mcp/items/:slug/content\", controllers.mcp.getItemContent);\n app.post(\"/api/marketplace/mcp/install\", controllers.mcp.install);\n app.post(\"/api/marketplace/mcp/manage\", controllers.mcp.manage);\n app.post(\"/api/marketplace/mcp/doctor\", controllers.mcp.doctor);\n app.get(\"/api/marketplace/mcp/recommendations\", controllers.mcp.getRecommendations);\n}\n","import * as NextclawCore from \"@nextclaw/core\";\nimport type { NcpSessionSkillsView, SessionSkillEntryView } from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport { loadConfigOrDefault } from \"@nextclaw-server/features/config/index.js\";\nimport type { UiRouterOptions } from \"@nextclaw-server/app/types/router-options.types.js\";\nimport { readNonEmptyString } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport { MARKETPLACE_ZH_COPY_BY_SLUG } from \"@nextclaw-server/features/marketplace/index.js\";\n\ntype SkillInfo = NextclawCore.SkillInfo;\ntype SkillsLoaderInstance = InstanceType<typeof NextclawCore.SkillsLoader>;\n\nconst SCOPE_SORT_ORDER: Record<SessionSkillEntryView[\"scope\"], number> = {\n project: 0,\n workspace: 1,\n builtin: 2,\n};\n\nexport class SessionSkillsViewBuilder {\n constructor(private readonly options: UiRouterOptions) {}\n\n build = (params: {\n sessionId: string;\n sessionMetadata?: Record<string, unknown> | null;\n }): NcpSessionSkillsView => {\n const config = loadConfigOrDefault(this.options.configPath);\n const projectContext = NextclawCore.resolveSessionProjectContext({\n sessionMetadata: params.sessionMetadata,\n workspace: NextclawCore.getWorkspacePathFromConfig(config),\n });\n const skillsLoader = new NextclawCore.SkillsLoader({\n workspace: projectContext.hostWorkspace,\n projectRoot: projectContext.projectRoot,\n });\n const availableRefs = new Set(\n skillsLoader.listSkills(true).map((skill) => skill.ref),\n );\n const records = skillsLoader\n .listSkills(false)\n .map((skill) => this.buildRecord(skill, skillsLoader, availableRefs))\n .sort((left, right) => this.compareRecords(left, right));\n\n return {\n sessionId: params.sessionId,\n total: records.length,\n refs: records.map((record) => record.ref),\n records,\n };\n };\n\n private buildRecord = (\n skill: SkillInfo,\n skillsLoader: SkillsLoaderInstance,\n availableRefs: Set<string>,\n ): SessionSkillEntryView => {\n const metadata = skillsLoader.getSkillMetadata(skill) ?? {};\n const description = readNonEmptyString(metadata.description);\n const descriptionZh =\n readNonEmptyString(metadata.description_zh) ??\n readNonEmptyString(metadata.descriptionZh) ??\n readNonEmptyString(MARKETPLACE_ZH_COPY_BY_SLUG[skill.name]?.description);\n\n return {\n ref: skill.ref,\n name: skill.name,\n path: skill.path,\n scope: skill.scope,\n source: skill.source,\n available: availableRefs.has(skill.ref),\n ...(description ? { description } : {}),\n ...(descriptionZh ? { descriptionZh } : {}),\n };\n };\n\n private compareRecords = (\n left: SessionSkillEntryView,\n right: SessionSkillEntryView,\n ): number => {\n const scopeCompare = SCOPE_SORT_ORDER[left.scope] - SCOPE_SORT_ORDER[right.scope];\n if (scopeCompare !== 0) {\n return scopeCompare;\n }\n const nameCompare = left.name.localeCompare(right.name);\n if (nameCompare !== 0) {\n return nameCompare;\n }\n return left.ref.localeCompare(right.ref);\n };\n}\n","import type { Context } from \"hono\";\nimport type {\n ChatSessionTypesView,\n SessionPatchUpdate,\n UiNcpSessionListView\n} from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport type { NcpSessionSummary } from \"@nextclaw/ncp\";\nimport { applySessionPreferencePatch } from \"@nextclaw-server/features/sessions/utils/session-preference-patch.utils.js\";\nimport {\n isSessionProjectRootValidationError,\n normalizeSessionProjectRoot,\n} from \"@nextclaw-server/features/sessions/utils/session-project-root.utils.js\";\nimport { SessionSkillsViewBuilder } from \"@nextclaw-server/features/sessions/services/session-skills-view.service.js\";\nimport { err, ok, readJson } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport type { UiRouterOptions } from \"@nextclaw-server/app/types/router-options.types.js\";\n\nfunction readPositiveInt(value: string | undefined): number | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const parsed = Number.parseInt(value, 10);\n if (!Number.isFinite(parsed) || parsed <= 0) {\n return undefined;\n }\n return parsed;\n}\n\nfunction readSessionMetadata(\n metadata: unknown,\n): Record<string, unknown> {\n if (!metadata || typeof metadata !== \"object\" || Array.isArray(metadata)) {\n return {};\n }\n return metadata as Record<string, unknown>;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction normalizeIdleSessionActivityPreview(session: NcpSessionSummary): NcpSessionSummary {\n const metadata = readSessionMetadata(session.metadata);\n const preview = metadata.last_activity_preview;\n if (!isRecord(preview) || preview.state !== \"running\") {\n return session;\n }\n return {\n ...session,\n metadata: {\n ...metadata,\n last_activity_preview: {\n ...preview,\n state: \"failed\",\n statusText: \"运行中断:上一轮请求没有完成,请重新发送。\",\n },\n },\n };\n}\n\nfunction applySessionTypePatch(\n metadata: Record<string, unknown>,\n patch: SessionPatchUpdate,\n): Record<string, unknown> {\n if (!Object.prototype.hasOwnProperty.call(patch, \"sessionType\")) {\n return metadata;\n }\n const sessionType = typeof patch.sessionType === \"string\" ? patch.sessionType.trim() : \"\";\n if (sessionType) {\n const { sessionType: _removed, ...nextMetadata } = metadata;\n void _removed;\n return {\n ...nextMetadata,\n session_type: sessionType,\n runtime: sessionType,\n };\n }\n const {\n runtime: _runtime,\n session_type: _sessionType,\n sessionType: _camelSessionType,\n ...nextMetadata\n } = metadata;\n void _runtime;\n void _sessionType;\n void _camelSessionType;\n return nextMetadata;\n}\n\nfunction applyUiReadAtPatch(\n metadata: Record<string, unknown>,\n patch: SessionPatchUpdate,\n): Record<string, unknown> {\n if (!Object.prototype.hasOwnProperty.call(patch, \"uiReadAt\")) {\n return metadata;\n }\n const uiReadAt = typeof patch.uiReadAt === \"string\" ? patch.uiReadAt.trim() : \"\";\n if (uiReadAt) {\n return {\n ...metadata,\n ui_last_read_at: uiReadAt,\n };\n }\n const { ui_last_read_at: _removed, ...nextMetadata } = metadata;\n void _removed;\n return nextMetadata;\n}\n\nfunction applyProjectRootPatch(\n metadata: Record<string, unknown>,\n projectRoot: string | null | undefined,\n): Record<string, unknown> {\n if (projectRoot === undefined) {\n return metadata;\n }\n if (projectRoot) {\n const { projectRoot: _removed, ...nextMetadata } = metadata;\n void _removed;\n return {\n ...nextMetadata,\n project_root: projectRoot,\n };\n }\n const { project_root: _projectRoot, projectRoot: _camelProjectRoot, ...nextMetadata } = metadata;\n void _projectRoot;\n void _camelProjectRoot;\n return nextMetadata;\n}\n\nfunction buildPatchedSessionMetadata(\n metadata: Record<string, unknown>,\n patch: SessionPatchUpdate,\n projectRootPatch: string | null | undefined,\n): Record<string, unknown> {\n const nextMetadata = applySessionPreferencePatch({\n metadata: structuredClone(metadata),\n patch,\n createInvalidThinkingError: () => new Error(\"PREFERRED_THINKING_INVALID\")\n });\n const nextMetadataWithSessionType = applySessionTypePatch(nextMetadata, patch);\n const nextMetadataWithReadAt = applyUiReadAtPatch(nextMetadataWithSessionType, patch);\n return applyProjectRootPatch(nextMetadataWithReadAt, projectRootPatch);\n}\n\nexport class NcpSessionRoutesController {\n private readonly sessionSkillsViewBuilder: SessionSkillsViewBuilder;\n\n constructor(private readonly options: UiRouterOptions) {\n this.sessionSkillsViewBuilder = new SessionSkillsViewBuilder(options);\n }\n\n private readonly withRuntimeStatus = (session: NcpSessionSummary): NcpSessionSummary =>\n this.options.kernel.isSessionRunning(session.sessionId)\n ? { ...session, status: \"running\" }\n : normalizeIdleSessionActivityPreview(session);\n\n readonly getSessionTypes = async (c: Context) => {\n const payload: ChatSessionTypesView = await this.options.kernel.listSessionTypes({\n describeMode: \"observation\",\n });\n return c.json(ok(payload));\n };\n\n readonly listSessions = async (c: Context) => {\n const sessionManager = this.options.kernel.sessionManager;\n const sessions = await sessionManager.listSessions({\n limit: readPositiveInt(c.req.query(\"limit\")),\n peerId: c.req.query(\"peerId\"),\n });\n const payload: UiNcpSessionListView = {\n sessions: sessions.map(this.withRuntimeStatus),\n total: sessions.length,\n };\n return c.json(ok(payload));\n };\n\n readonly getSession = async (c: Context) => {\n const sessionManager = this.options.kernel.sessionManager;\n const sessionId = decodeURIComponent(c.req.param(\"sessionId\"));\n const session = await sessionManager.getSession(sessionId);\n if (!session) {\n return c.json(err(\"NOT_FOUND\", `ncp session not found: ${sessionId}`), 404);\n }\n return c.json(ok(this.withRuntimeStatus(session)));\n };\n\n readonly listSessionMessages = async (c: Context) => {\n const sessionManager = this.options.kernel.sessionManager;\n const sessionId = decodeURIComponent(c.req.param(\"sessionId\"));\n const session = await sessionManager.getSession(sessionId);\n if (!session) {\n return c.json(err(\"NOT_FOUND\", `ncp session not found: ${sessionId}`), 404);\n }\n\n const messages = await sessionManager.listSessionMessages(sessionId, {\n limit: readPositiveInt(c.req.query(\"limit\")),\n });\n const sessionWithRuntimeStatus = this.withRuntimeStatus(session);\n const payload = {\n sessionId,\n status: sessionWithRuntimeStatus.status ?? \"idle\",\n messages,\n ...(sessionWithRuntimeStatus.contextWindow ? { contextWindow: sessionWithRuntimeStatus.contextWindow } : {}),\n total: messages.length,\n };\n return c.json(ok(payload));\n };\n\n readonly getSessionSkills = async (c: Context) => {\n const sessionManager = this.options.kernel.sessionManager;\n const sessionId = decodeURIComponent(c.req.param(\"sessionId\"));\n const query = c.req.query();\n const hasProjectRootOverride = Object.prototype.hasOwnProperty.call(query, \"projectRoot\");\n const existing = await sessionManager.getSession(sessionId);\n const metadata = readSessionMetadata(existing?.metadata);\n\n if (hasProjectRootOverride) {\n try {\n const projectRoot = await normalizeSessionProjectRoot(query.projectRoot);\n if (projectRoot) {\n metadata.project_root = projectRoot;\n } else {\n delete metadata.project_root;\n delete metadata.projectRoot;\n }\n } catch (error) {\n if (isSessionProjectRootValidationError(error)) {\n return c.json(err(error.code, error.message), 400);\n }\n throw error;\n }\n }\n\n return c.json(ok(this.sessionSkillsViewBuilder.build({\n sessionId,\n sessionMetadata: metadata,\n })));\n };\n\n readonly patchSession = async (c: Context) => {\n const sessionManager = this.options.kernel.sessionManager;\n const sessionId = decodeURIComponent(c.req.param(\"sessionId\"));\n const body = await readJson<Record<string, unknown>>(c.req.raw);\n if (!body.ok || !body.data || typeof body.data !== \"object\") {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n\n const patch = body.data as SessionPatchUpdate;\n if (patch.clearHistory) {\n return c.json(err(\"UNSUPPORTED_PATCH\", \"clearHistory is not supported for ncp sessions\"), 400);\n }\n\n let patched;\n try {\n const projectRootPatch = Object.prototype.hasOwnProperty.call(patch, \"projectRoot\")\n ? await normalizeSessionProjectRoot(patch.projectRoot)\n : undefined;\n const existing = await sessionManager.getSessionRecord(sessionId);\n const metadata = buildPatchedSessionMetadata(\n readSessionMetadata(existing?.metadata),\n patch,\n projectRootPatch,\n );\n patched = existing\n ? await sessionManager.setSessionMetadata(sessionId, metadata)\n : Boolean(await sessionManager.updateSession(sessionId, { metadata }));\n } catch (error) {\n if (error instanceof Error && error.message === \"PREFERRED_THINKING_INVALID\") {\n return c.json(err(\"PREFERRED_THINKING_INVALID\", \"preferredThinking must be a supported thinking level\"), 400);\n }\n if (isSessionProjectRootValidationError(error)) {\n return c.json(err(error.code, error.message), 400);\n }\n throw error;\n }\n\n if (!patched) return c.json(err(\"NOT_FOUND\", `ncp session not found: ${sessionId}`), 404);\n\n const updated = await sessionManager.getSession(sessionId);\n if (!updated) {\n return c.json(err(\"NOT_FOUND\", `ncp session not found: ${sessionId}`), 404);\n }\n\n return c.json(ok(this.withRuntimeStatus(updated)));\n };\n\n readonly deleteSession = async (c: Context) => {\n const sessionManager = this.options.kernel.sessionManager;\n const sessionId = decodeURIComponent(c.req.param(\"sessionId\"));\n const existing = await sessionManager.getSession(sessionId);\n if (!existing) {\n return c.json(err(\"NOT_FOUND\", `ncp session not found: ${sessionId}`), 404);\n }\n\n await sessionManager.deleteSession(sessionId);\n return c.json(ok({ deleted: true, sessionId }));\n };\n}\n","import type { Context } from \"hono\";\nimport type {\n RemoteAccountProfileUpdateRequest,\n RemoteBrowserAuthPollRequest,\n RemoteBrowserAuthStartRequest,\n RemoteLoginRequest,\n RemoteServiceAction,\n RemoteSettingsUpdateRequest\n} from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport { err, formatUserFacingError, ok, readJson, readNonEmptyString } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport type { UiRemoteAccessHost } from \"@nextclaw-server/app/types/router-options.types.js\";\n\nconst REMOTE_SERVICE_ACTIONS = new Set<RemoteServiceAction>([\"start\", \"restart\", \"stop\"]);\n\nfunction readTrimmedString(value: unknown): string | undefined {\n return typeof value === \"string\" ? value.trim() : undefined;\n}\n\nexport class RemoteRoutesController {\n constructor(private readonly host: UiRemoteAccessHost) {}\n\n readonly getStatus = async (c: Context) => {\n try {\n return c.json(ok(await this.host.getStatus()));\n } catch (error) {\n return c.json(err(\"REMOTE_STATUS_FAILED\", formatUserFacingError(error)), 500);\n }\n };\n\n readonly getDoctor = async (c: Context) => {\n try {\n return c.json(ok(await this.host.runDoctor()));\n } catch (error) {\n return c.json(err(\"REMOTE_DOCTOR_FAILED\", formatUserFacingError(error)), 500);\n }\n };\n\n readonly login = async (c: Context) => {\n const body = await readJson<RemoteLoginRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n\n const email = readNonEmptyString(body.data.email);\n const password = readNonEmptyString(body.data.password);\n if (!email || !password) {\n return c.json(err(\"INVALID_BODY\", \"email and password are required\"), 400);\n }\n\n try {\n return c.json(ok(await this.host.login({\n email,\n password,\n apiBase: readTrimmedString(body.data.apiBase)\n })));\n } catch (error) {\n return c.json(err(\"REMOTE_LOGIN_FAILED\", formatUserFacingError(error)), 400);\n }\n };\n\n readonly startBrowserAuth = async (c: Context) => {\n const body = await readJson<RemoteBrowserAuthStartRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n\n try {\n return c.json(ok(await this.host.startBrowserAuth({\n apiBase: readTrimmedString(body.data.apiBase)\n })));\n } catch (error) {\n return c.json(err(\"REMOTE_BROWSER_AUTH_START_FAILED\", formatUserFacingError(error)), 400);\n }\n };\n\n readonly pollBrowserAuth = async (c: Context) => {\n const body = await readJson<RemoteBrowserAuthPollRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n\n const sessionId = readNonEmptyString(body.data.sessionId);\n if (!sessionId) {\n return c.json(err(\"INVALID_BODY\", \"sessionId is required\"), 400);\n }\n\n try {\n return c.json(ok(await this.host.pollBrowserAuth({\n sessionId,\n apiBase: readTrimmedString(body.data.apiBase)\n })));\n } catch (error) {\n return c.json(err(\"REMOTE_BROWSER_AUTH_POLL_FAILED\", formatUserFacingError(error)), 400);\n }\n };\n\n readonly logout = async (c: Context) => {\n try {\n return c.json(ok(await this.host.logout()));\n } catch (error) {\n return c.json(err(\"REMOTE_LOGOUT_FAILED\", formatUserFacingError(error)), 500);\n }\n };\n\n readonly updateProfile = async (c: Context) => {\n const body = await readJson<RemoteAccountProfileUpdateRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n\n const username = readNonEmptyString(body.data.username);\n if (!username) {\n return c.json(err(\"INVALID_BODY\", \"username is required\"), 400);\n }\n\n try {\n return c.json(ok(await this.host.updateProfile({ username })));\n } catch (error) {\n return c.json(err(\"REMOTE_PROFILE_UPDATE_FAILED\", formatUserFacingError(error)), 400);\n }\n };\n\n readonly updateSettings = async (c: Context) => {\n const body = await readJson<RemoteSettingsUpdateRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n\n try {\n return c.json(ok(await this.host.updateSettings({\n enabled: typeof body.data.enabled === \"boolean\" ? body.data.enabled : undefined,\n deviceName: readTrimmedString(body.data.deviceName),\n platformApiBase: readTrimmedString(body.data.platformApiBase)\n })));\n } catch (error) {\n return c.json(err(\"REMOTE_SETTINGS_FAILED\", formatUserFacingError(error)), 400);\n }\n };\n\n readonly controlService = async (c: Context) => {\n const action = c.req.param(\"action\");\n if (!REMOTE_SERVICE_ACTIONS.has(action as RemoteServiceAction)) {\n return c.json(err(\"INVALID_ACTION\", \"unsupported remote service action\"), 400);\n }\n\n try {\n return c.json(ok(await this.host.controlService(action as RemoteServiceAction)));\n } catch (error) {\n return c.json(err(\"REMOTE_SERVICE_FAILED\", formatUserFacingError(error)), 400);\n }\n };\n}\n","import type { Context } from \"hono\";\nimport { err, formatUserFacingError, ok } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport type { UiRuntimeControlHost } from \"@nextclaw-server/app/types/router-options.types.js\";\n\nexport class RuntimeControlRoutesController {\n constructor(private readonly host: UiRuntimeControlHost) {}\n\n readonly getControl = async (c: Context) => {\n try {\n return c.json(ok(await this.host.getControl()));\n } catch (error) {\n return c.json(err(\"RUNTIME_CONTROL_FAILED\", formatUserFacingError(error)), 500);\n }\n };\n\n readonly restartService = async (c: Context) => {\n try {\n return c.json(ok(await this.host.restartService()));\n } catch (error) {\n return c.json(err(\"RUNTIME_RESTART_FAILED\", formatUserFacingError(error)), 400);\n }\n };\n\n readonly startService = async (c: Context) => {\n try {\n return c.json(ok(await this.host.startService()));\n } catch (error) {\n return c.json(err(\"RUNTIME_START_FAILED\", formatUserFacingError(error)), 400);\n }\n };\n\n readonly stopService = async (c: Context) => {\n try {\n return c.json(ok(await this.host.stopService()));\n } catch (error) {\n return c.json(err(\"RUNTIME_STOP_FAILED\", formatUserFacingError(error)), 400);\n }\n };\n}\n","import type { Context } from \"hono\";\nimport type { UpdatePreferences, UpdateSnapshot } from \"@nextclaw/shared\";\nimport { err, formatUserFacingError, ok, readJson } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport type { UiRuntimeUpdateHost } from \"@nextclaw-server/app/types/router-options.types.js\";\n\ntype RuntimeUpdatePreferencesRequest = Partial<UpdatePreferences>;\ntype RuntimeUpdateChannelRequest = {\n channel?: UpdateSnapshot[\"channel\"];\n};\n\nexport class RuntimeUpdateRoutesController {\n constructor(private readonly host: UiRuntimeUpdateHost) {}\n\n readonly getState = async (c: Context) => {\n try {\n return c.json(ok(await this.host.getState()));\n } catch (error) {\n return c.json(err(\"RUNTIME_UPDATE_STATE_FAILED\", formatUserFacingError(error)), 500);\n }\n };\n\n readonly checkForUpdates = async (c: Context) => {\n try {\n return c.json(ok(await this.host.checkForUpdates()));\n } catch (error) {\n return c.json(err(\"RUNTIME_UPDATE_CHECK_FAILED\", formatUserFacingError(error)), 400);\n }\n };\n\n readonly downloadUpdate = async (c: Context) => {\n try {\n return c.json(ok(await this.host.downloadUpdate()));\n } catch (error) {\n return c.json(err(\"RUNTIME_UPDATE_DOWNLOAD_FAILED\", formatUserFacingError(error)), 400);\n }\n };\n\n readonly applyDownloadedUpdate = async (c: Context) => {\n try {\n return c.json(ok(await this.host.applyDownloadedUpdate()));\n } catch (error) {\n return c.json(err(\"RUNTIME_UPDATE_APPLY_FAILED\", formatUserFacingError(error)), 400);\n }\n };\n\n readonly updatePreferences = async (c: Context) => {\n const body = await readJson<RuntimeUpdatePreferencesRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n\n try {\n return c.json(ok(await this.host.updatePreferences({\n ...(typeof body.data.automaticChecks === \"boolean\" ? { automaticChecks: body.data.automaticChecks } : {}),\n ...(typeof body.data.autoDownload === \"boolean\" ? { autoDownload: body.data.autoDownload } : {})\n })));\n } catch (error) {\n return c.json(err(\"RUNTIME_UPDATE_PREFERENCES_FAILED\", formatUserFacingError(error)), 400);\n }\n };\n\n readonly updateChannel = async (c: Context) => {\n const body = await readJson<RuntimeUpdateChannelRequest>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid json body\"), 400);\n }\n\n const channel = body.data.channel;\n if (channel !== \"stable\" && channel !== \"beta\") {\n return c.json(err(\"INVALID_BODY\", \"channel must be stable or beta\"), 400);\n }\n\n try {\n return c.json(ok(await this.host.updateChannel(channel)));\n } catch (error) {\n return c.json(err(\"RUNTIME_UPDATE_CHANNEL_FAILED\", formatUserFacingError(error)), 400);\n }\n };\n}\n","import type { Context } from \"hono\";\nimport {\n isPanelAppError,\n PanelAppError,\n type PanelAppAgentCapability,\n type PanelAppManager,\n} from \"@nextclaw/kernel\";\nimport type {\n PanelAppAgentGenerateObjectRequestView,\n PanelAppAgentSendRequestView,\n PanelAppBridgeSessionCreateRequest,\n} from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport {\n err,\n isRecord,\n ok,\n readJson,\n} from \"@nextclaw-server/shared/utils/http-response.utils.js\";\n\nconst PANEL_BRIDGE_SESSION_HEADER = \"x-nextclaw-panel-bridge-session\";\n\nfunction createPanelAppResourceHeaders(contentType: string): Record<string, string> {\n return {\n \"content-type\": contentType,\n \"cache-control\": \"no-store\",\n \"access-control-allow-origin\": \"*\",\n };\n}\n\nfunction statusForPanelAppError(code: string): 400 | 401 | 403 | 404 | 408 {\n switch (code) {\n case \"AUTHORIZATION_REQUIRED\":\n return 401;\n case \"PANEL_APP_CAPABILITY_NOT_DECLARED\":\n case \"PANEL_APP_CLIENT_NOT_DECLARED\":\n return 403;\n case \"PANEL_APP_NOT_FOUND\":\n case \"PANEL_APP_BRIDGE_SESSION_NOT_FOUND\":\n return 404;\n case \"PANEL_APP_ASSET_TOKEN_EXPIRED\":\n case \"PANEL_APP_ASSET_TOKEN_INVALID\":\n return 401;\n case \"PANEL_APP_INVALID_ASSET_PATH\":\n case \"PANEL_APP_MANIFEST_INVALID\":\n return 400;\n case \"AGENT_OBJECT_RESULT_TIMEOUT\":\n return 408;\n default:\n return 400;\n }\n}\n\nexport class PanelAppsRoutesController {\n constructor(\n private readonly panelAppManager: PanelAppManager,\n private readonly params: {\n panelAppClientSdkScript?: () => Promise<string> | string;\n } = {},\n ) {}\n\n readonly list = async (c: Context) => {\n const payload = await this.panelAppManager.listPanelApps();\n return c.json(ok(payload));\n };\n\n readonly updatePanelAppPreferences = async (c: Context) => {\n const body = await readJson<unknown>(c.req.raw);\n if (!body.ok || !isRecord(body.data)) {\n return c.json(err(\"INVALID_PANEL_APP_PREFERENCES\", \"invalid panel app preferences\"), 400);\n }\n try {\n const preferences = typeof body.data.favorite === \"boolean\"\n ? { favorite: body.data.favorite }\n : {};\n const payload = await this.panelAppManager.updatePanelAppPreferences(\n c.req.param(\"id\"),\n preferences,\n );\n return c.json(ok(payload));\n } catch (error) {\n if (isPanelAppError(error)) {\n return c.json(\n err(error.code, error.message),\n statusForPanelAppError(error.code),\n );\n }\n throw error;\n }\n };\n\n readonly recordPanelAppOpened = async (c: Context) => {\n try {\n const payload = await this.panelAppManager.recordPanelAppOpened(c.req.param(\"id\"));\n return c.json(ok(payload));\n } catch (error) {\n if (isPanelAppError(error)) {\n return c.json(\n err(error.code, error.message),\n statusForPanelAppError(error.code),\n );\n }\n throw error;\n }\n };\n\n readonly deletePanelApp = async (c: Context) => {\n try {\n const payload = await this.panelAppManager.deletePanelApp(c.req.param(\"id\"));\n return c.json(ok(payload));\n } catch (error) {\n if (isPanelAppError(error)) {\n return c.json(\n err(error.code, error.message),\n statusForPanelAppError(error.code),\n );\n }\n throw error;\n }\n };\n\n readonly getPanelAppContent = async (c: Context): Promise<Response> => {\n try {\n const payload = await this.panelAppManager.getPanelAppContent(\n c.req.param(\"id\"),\n );\n return new Response(payload.html, {\n headers: {\n \"content-type\": payload.contentType,\n \"cache-control\": \"no-store\",\n },\n });\n } catch (error) {\n if (isPanelAppError(error)) {\n return c.json(\n err(error.code, error.message),\n statusForPanelAppError(error.code),\n );\n }\n throw error;\n }\n };\n\n readonly getPanelAppAsset = async (c: Context): Promise<Response> => {\n try {\n const payload = await this.panelAppManager.getPanelAppAsset(\n c.req.param(\"id\"),\n readAssetPath(c.req.raw.url),\n );\n return new Response(payload.content, {\n headers: createPanelAppResourceHeaders(payload.contentType),\n });\n } catch (error) {\n if (isPanelAppError(error)) {\n return c.json(\n err(error.code, error.message),\n statusForPanelAppError(error.code),\n );\n }\n throw error;\n }\n };\n\n readonly getPanelAppAssetByToken = async (c: Context): Promise<Response> => {\n try {\n const payload = await this.panelAppManager.getPanelAppAssetByToken(\n c.req.param(\"token\"),\n readTokenizedAssetPath(c.req.raw.url, c.req.param(\"token\")),\n );\n return new Response(payload.content, {\n headers: createPanelAppResourceHeaders(payload.contentType),\n });\n } catch (error) {\n if (isPanelAppError(error)) {\n return c.json(\n err(error.code, error.message),\n statusForPanelAppError(error.code),\n );\n }\n throw error;\n }\n };\n\n readonly getPanelAppBridgeScript = (): Response => {\n return new Response(this.panelAppManager.getPanelAppBridgeScript(), {\n headers: {\n \"content-type\": \"application/javascript; charset=utf-8\",\n \"cache-control\": \"no-store\",\n },\n });\n };\n\n readonly getPanelAppClientSdkScript = async (): Promise<Response> => {\n if (!this.params.panelAppClientSdkScript) {\n return new Response(\"Panel App client SDK script is not configured.\", {\n status: 404,\n headers: {\n \"content-type\": \"text/plain; charset=utf-8\",\n \"cache-control\": \"no-store\",\n },\n });\n }\n return new Response(await this.params.panelAppClientSdkScript(), {\n headers: createPanelAppResourceHeaders(\"application/javascript; charset=utf-8\"),\n });\n };\n\n readonly createBridgeSession = async (c: Context) => {\n const body = await readJson<PanelAppBridgeSessionCreateRequest>(c.req.raw);\n if (\n !body.ok ||\n !isRecord(body.data) ||\n (typeof body.data.panelAppId !== \"string\" && typeof body.data.appId !== \"string\")\n ) {\n return c.json(err(\"INVALID_PANEL_APP_BRIDGE_SESSION\", \"invalid bridge session request\"), 400);\n }\n const panelAppId = typeof body.data.appId === \"string\"\n ? body.data.appId\n : body.data.panelAppId;\n if (typeof panelAppId !== \"string\") {\n return c.json(err(\"INVALID_PANEL_APP_BRIDGE_SESSION\", \"invalid bridge session request\"), 400);\n }\n try {\n const session = await this.panelAppManager.createPanelAppBridgeSession({\n id: panelAppId,\n });\n return c.json(ok({\n id: session.id,\n token: session.token,\n appId: session.appId,\n expiresAt: session.expiresAt,\n }));\n } catch (error) {\n if (isPanelAppError(error)) {\n return c.json(\n err(error.code, error.message),\n statusForPanelAppError(error.code),\n );\n }\n throw error;\n }\n };\n\n readonly deleteBridgeSession = (c: Context) => {\n this.panelAppManager.deletePanelAppBridgeSession(c.req.param(\"token\"));\n return c.json(ok({ deleted: true }));\n };\n\n readonly grantClient = async (c: Context) => {\n try {\n return c.json(ok(await this.panelAppManager.grantPanelAppClient(\n c.req.param(\"appId\"),\n )));\n } catch (error) {\n return this.handlePanelAppError(c, error);\n }\n };\n\n readonly revokeClient = async (c: Context) => {\n try {\n await this.panelAppManager.revokePanelAppClient(c.req.param(\"appId\"));\n return c.json(ok({ revoked: true }));\n } catch (error) {\n return this.handlePanelAppError(c, error);\n }\n };\n\n readonly sendAgentMessage = async (c: Context) => {\n const body = await readJson<PanelAppAgentSendRequestView>(c.req.raw);\n if (!body.ok || !isRecord(body.data) || !isRecord(body.data.payload)) {\n return c.json(err(\"INVALID_PANEL_APP_AGENT_REQUEST\", \"invalid agent send request\"), 400);\n }\n try {\n return c.json(ok(await this.panelAppManager.sendAgentMessage(\n this.requireBridgeSessionToken(c),\n body.data.payload,\n )));\n } catch (error) {\n return this.handlePanelAppError(c, error);\n }\n };\n\n readonly generateAgentObject = async (c: Context) => {\n const body = await readJson<PanelAppAgentGenerateObjectRequestView>(c.req.raw);\n if (!body.ok || !isRecord(body.data) || !isRecord(body.data.input)) {\n return c.json(err(\"INVALID_PANEL_APP_AGENT_REQUEST\", \"invalid generateObject request\"), 400);\n }\n try {\n return c.json(ok(await this.panelAppManager.generateAgentObject(\n this.requireBridgeSessionToken(c),\n body.data.input,\n )));\n } catch (error) {\n return this.handlePanelAppError(c, error);\n }\n };\n\n readonly grantAgentCapability = async (c: Context) => {\n try {\n return c.json(ok(await this.panelAppManager.grantAgentCapability(\n this.requireBridgeSessionToken(c),\n c.req.param(\"capability\") as PanelAppAgentCapability,\n )));\n } catch (error) {\n return this.handlePanelAppError(c, error);\n }\n };\n\n private requireBridgeSessionToken = (c: Context): string => {\n const token = c.req.raw.headers.get(PANEL_BRIDGE_SESSION_HEADER)?.trim();\n if (!token) {\n throw new Error(\"panel app bridge session is required\");\n }\n return token;\n };\n\n private handlePanelAppError = (c: Context, error: unknown) => {\n if (isPanelAppError(error)) {\n return c.json(\n err(error.code, error.message),\n statusForPanelAppError(error.code),\n );\n }\n if (error instanceof Error && error.message === \"panel app bridge session is required\") {\n return c.json(err(\"PANEL_APP_BRIDGE_SESSION_REQUIRED\", error.message), 401);\n }\n throw error;\n };\n}\n\nfunction readAssetPath(url: string): string {\n const pathname = new URL(url).pathname;\n const marker = \"/assets/\";\n const markerIndex = pathname.indexOf(marker);\n if (markerIndex < 0) {\n return \"\";\n }\n try {\n return decodeURIComponent(pathname.slice(markerIndex + marker.length));\n } catch {\n throw new PanelAppError(\"PANEL_APP_INVALID_ASSET_PATH\", \"invalid panel app asset path\");\n }\n}\n\nfunction readTokenizedAssetPath(url: string, token: string): string {\n const pathname = new URL(url).pathname;\n const marker = `/api/panel-app-assets/${encodeURIComponent(token)}/`;\n if (!pathname.startsWith(marker)) {\n return \"\";\n }\n try {\n return decodeURIComponent(pathname.slice(marker.length));\n } catch {\n throw new PanelAppError(\"PANEL_APP_INVALID_ASSET_PATH\", \"invalid panel app asset path\");\n }\n}\n","import type { Context } from \"hono\";\nimport {\n isPreferenceError,\n type PreferenceManager,\n} from \"@nextclaw/kernel\";\nimport type {\n PreferenceDeleteResult,\n PreferenceEntryView,\n PreferenceUpdateRequest,\n} from \"@nextclaw-server/features/preferences/types/preferences-api.types.js\";\nimport {\n err,\n isRecord,\n ok,\n readJson,\n} from \"@nextclaw-server/shared/utils/http-response.utils.js\";\n\nfunction statusForPreferenceError(code: string): 400 {\n void code;\n return 400;\n}\n\nexport class PreferencesRoutesController {\n constructor(private readonly preferenceManager: PreferenceManager) {}\n\n readonly get = async (c: Context) => {\n try {\n const entry = await this.preferenceManager.getPreference(c.req.param(\"key\"));\n const payload: PreferenceEntryView = entry\n ? {\n key: entry.key,\n value: entry.value,\n updatedAt: entry.updatedAt,\n }\n : {\n key: c.req.param(\"key\"),\n value: null,\n };\n return c.json(ok(payload));\n } catch (error) {\n if (isPreferenceError(error)) {\n return c.json(\n err(error.code, error.message),\n statusForPreferenceError(error.code),\n );\n }\n throw error;\n }\n };\n\n readonly update = async (c: Context) => {\n const body = await readJson<PreferenceUpdateRequest>(c.req.raw);\n if (!body.ok || !isRecord(body.data) || !Object.hasOwn(body.data, \"value\")) {\n return c.json(err(\"INVALID_PREFERENCE\", \"preference value is required\"), 400);\n }\n try {\n const entry = await this.preferenceManager.setPreference(\n c.req.param(\"key\"),\n body.data.value,\n );\n return c.json(ok({\n key: entry.key,\n value: entry.value,\n updatedAt: entry.updatedAt,\n } satisfies PreferenceEntryView));\n } catch (error) {\n if (isPreferenceError(error)) {\n return c.json(\n err(error.code, error.message),\n statusForPreferenceError(error.code),\n );\n }\n throw error;\n }\n };\n\n readonly delete = async (c: Context) => {\n try {\n const key = c.req.param(\"key\");\n const deleted = await this.preferenceManager.deletePreference(key);\n return c.json(ok({\n key,\n deleted,\n } satisfies PreferenceDeleteResult));\n } catch (error) {\n if (isPreferenceError(error)) {\n return c.json(\n err(error.code, error.message),\n statusForPreferenceError(error.code),\n );\n }\n throw error;\n }\n };\n}\n","import type { Context } from \"hono\";\nimport {\n isPanelAppError,\n isServiceAppError,\n type PanelAppManager,\n type ServiceAppManager,\n} from \"@nextclaw/kernel\";\nimport {\n err,\n isRecord,\n ok,\n readJson,\n} from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport type {\n ServiceActionGrantBatchRequestView,\n ServiceActionInvokeRequestView,\n} from \"@nextclaw-server/shared/types/server-api.types.js\";\n\nconst PANEL_BRIDGE_SESSION_HEADER = \"x-nextclaw-panel-bridge-session\";\n\nfunction statusForServiceAppError(code: string): 400 | 401 | 403 | 404 {\n switch (code) {\n case \"AUTHORIZATION_REQUIRED\":\n return 401;\n case \"SERVICE_APP_ACTION_NOT_DECLARED\":\n return 403;\n case \"SERVICE_APP_ACTION_NOT_FOUND\":\n case \"SERVICE_APP_NOT_FOUND\":\n return 404;\n default:\n return 400;\n }\n}\n\nexport class ServiceAppsRoutesController {\n constructor(private readonly params: {\n panelAppManager: PanelAppManager;\n serviceAppManager: ServiceAppManager;\n }) {}\n\n readonly listServiceApps = async (c: Context) => {\n return c.json(ok(await this.params.serviceAppManager.listServiceApps()));\n };\n\n readonly getServiceApp = async (c: Context) => {\n try {\n return c.json(ok(await this.params.serviceAppManager.getServiceApp(c.req.param(\"appId\"))));\n } catch (error) {\n return this.handleServiceAppError(c, error);\n }\n };\n\n readonly listServiceActions = async (c: Context) => {\n try {\n const bridgeSession = this.readOptionalBridgeSession(c);\n const appId = c.req.query(\"appId\")?.trim();\n const actions = await this.params.serviceAppManager.listServiceActions(\n bridgeSession\n ? {\n caller: bridgeSession.caller,\n appId,\n declaredActions: bridgeSession.declaredActions,\n }\n : { appId },\n );\n return c.json(ok({ actions }));\n } catch (error) {\n return this.handleServiceAppError(c, error);\n }\n };\n\n readonly discoverServiceAppActions = async (c: Context) => {\n try {\n const actions = await this.params.serviceAppManager.discoverServiceAppActions(\n c.req.param(\"appId\"),\n );\n return c.json(ok({ actions }));\n } catch (error) {\n return this.handleServiceAppError(c, error);\n }\n };\n\n readonly invokeServiceAction = async (c: Context) => {\n const body = await readJson<ServiceActionInvokeRequestView>(c.req.raw);\n if (!body.ok || (body.data !== undefined && !isRecord(body.data))) {\n return c.json(err(\"INVALID_SERVICE_ACTION_REQUEST\", \"invalid service action request\"), 400);\n }\n try {\n const bridgeSession = this.requireBridgeSession(c);\n const payload = await this.params.serviceAppManager.invokeServiceAction(\n c.req.param(\"actionId\"),\n {\n caller: bridgeSession.caller,\n declaredActions: bridgeSession.declaredActions,\n input: isRecord(body.data.input) ? body.data.input : {},\n },\n );\n return c.json(ok(payload));\n } catch (error) {\n return this.handleServiceAppError(c, error);\n }\n };\n\n readonly grantServiceAction = async (c: Context) => {\n try {\n const bridgeSession = this.requireBridgeSession(c);\n const payload = await this.params.serviceAppManager.grantServiceAction(\n c.req.param(\"actionId\"),\n {\n caller: bridgeSession.caller,\n declaredActions: bridgeSession.declaredActions,\n },\n );\n return c.json(ok(payload));\n } catch (error) {\n return this.handleServiceAppError(c, error);\n }\n };\n\n readonly grantServiceActions = async (c: Context) => {\n const body = await readJson<ServiceActionGrantBatchRequestView>(c.req.raw);\n if (!body.ok || !Array.isArray(body.data?.actionIds)) {\n return c.json(err(\"INVALID_SERVICE_ACTION_GRANT_REQUEST\", \"invalid service action grant request\"), 400);\n }\n try {\n const bridgeSession = this.requireBridgeSession(c);\n const grants = await this.params.serviceAppManager.grantServiceActions(\n body.data.actionIds,\n {\n caller: bridgeSession.caller,\n declaredActions: bridgeSession.declaredActions,\n },\n );\n return c.json(ok({ grants }));\n } catch (error) {\n return this.handleServiceAppError(c, error);\n }\n };\n\n readonly listServiceActionGrants = async (c: Context) => {\n return c.json(ok({\n grants: await this.params.serviceAppManager.listServiceActionGrants(),\n }));\n };\n\n readonly revokeServiceAction = async (c: Context) => {\n try {\n const bridgeSession = this.requireBridgeSession(c);\n await this.params.serviceAppManager.revokeServiceAction(\n bridgeSession.caller,\n c.req.param(\"actionId\"),\n );\n return c.json(ok({ revoked: true }));\n } catch (error) {\n return this.handleServiceAppError(c, error);\n }\n };\n\n readonly revokeServiceActionGrant = async (c: Context) => {\n const caller = this.readCallerQuery(c);\n if (!caller) {\n return c.json(err(\"INVALID_SERVICE_ACTION_CALLER\", \"invalid service action caller\"), 400);\n }\n try {\n await this.params.serviceAppManager.revokeServiceAction(\n caller,\n c.req.param(\"actionId\"),\n );\n return c.json(ok({ revoked: true }));\n } catch (error) {\n return this.handleServiceAppError(c, error);\n }\n };\n\n readonly restartServiceApp = async (c: Context) => {\n try {\n return c.json(ok(await this.params.serviceAppManager.restartServiceApp(c.req.param(\"appId\"))));\n } catch (error) {\n return this.handleServiceAppError(c, error);\n }\n };\n\n readonly deleteServiceApp = async (c: Context) => {\n try {\n return c.json(ok(await this.params.serviceAppManager.deleteServiceApp(c.req.param(\"appId\"))));\n } catch (error) {\n return this.handleServiceAppError(c, error);\n }\n };\n\n private requireBridgeSession = (c: Context) => {\n const token = c.req.raw.headers.get(PANEL_BRIDGE_SESSION_HEADER)?.trim();\n if (!token) {\n throw new Error(\"panel app bridge session is required\");\n }\n return this.params.panelAppManager.resolvePanelAppBridgeSession(token);\n };\n\n private readOptionalBridgeSession = (c: Context) => {\n const token = c.req.raw.headers.get(PANEL_BRIDGE_SESSION_HEADER)?.trim();\n return token\n ? this.params.panelAppManager.resolvePanelAppBridgeSession(token)\n : null;\n };\n\n private readCallerQuery = (c: Context) => {\n const surface = c.req.query(\"surface\");\n const appId = c.req.query(\"appId\")?.trim();\n if (surface !== \"panel-app\" || !appId) {\n return null;\n }\n return { surface, appId } as const;\n };\n\n private handleServiceAppError = (c: Context, error: unknown) => {\n if (isServiceAppError(error)) {\n return c.json(\n err(error.code, error.message),\n statusForServiceAppError(error.code),\n );\n }\n if (isPanelAppError(error)) {\n return c.json(err(error.code, error.message), 404);\n }\n if (error instanceof Error && error.message === \"panel app bridge session is required\") {\n return c.json(err(\"PANEL_APP_BRIDGE_SESSION_REQUIRED\", error.message), 401);\n }\n throw error;\n };\n}\n","import type { NcpEndpointEvent, NcpStreamRequestPayload } from \"@nextclaw/ncp\";\nimport { eventKeys, type EventBus, type Unsubscribe } from \"@nextclaw/shared\";\n\nfunction readEventSessionId(event: NcpEndpointEvent): string | null {\n const payload = \"payload\" in event ? event.payload : null;\n if (!payload || typeof payload !== \"object\") {\n return null;\n }\n return \"sessionId\" in payload && typeof payload.sessionId === \"string\"\n ? payload.sessionId\n : null;\n}\n\nfunction toSseFrame(eventName: string, data: unknown): string {\n return `event: ${eventName}\\ndata: ${JSON.stringify(data)}\\n\\n`;\n}\n\nexport function createNcpSessionEventStreamResponse(\n eventBus: Pick<EventBus, \"on\">,\n payload: NcpStreamRequestPayload,\n signal: AbortSignal,\n): Response {\n const encoder = new TextEncoder();\n let controller: ReadableStreamDefaultController<Uint8Array> | null = null;\n let closed = false;\n let unsubscribe: Unsubscribe = () => undefined;\n const cleanup = () => {\n unsubscribe();\n signal.removeEventListener(\"abort\", close);\n };\n const close = () => {\n if (closed) {\n return;\n }\n closed = true;\n cleanup();\n controller?.close();\n };\n const push = (event: NcpEndpointEvent) => {\n if (closed || signal.aborted) {\n return;\n }\n if (readEventSessionId(event) === payload.sessionId) {\n controller?.enqueue(encoder.encode(toSseFrame(\"ncp-event\", event)));\n }\n };\n const stream = new ReadableStream<Uint8Array>({\n start: (streamController) => {\n controller = streamController;\n unsubscribe = eventBus.on(eventKeys.ncpEvent, push);\n signal.addEventListener(\"abort\", close, { once: true });\n if (signal.aborted) {\n close();\n }\n },\n cancel: () => {\n if (!closed) {\n closed = true;\n cleanup();\n }\n },\n });\n return new Response(stream, {\n headers: {\n \"Content-Type\": \"text/event-stream; charset=utf-8\",\n \"Cache-Control\": \"no-cache, no-transform\",\n Connection: \"keep-alive\",\n \"X-Accel-Buffering\": \"no\",\n },\n });\n}\n","import { readdir, stat } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, parse, resolve } from \"node:path\";\nimport { expandHome } from \"@nextclaw/core\";\nimport type {\n ServerPathBreadcrumbView,\n ServerPathBrowseView,\n ServerPathEntryView,\n} from \"@nextclaw-server/shared/types/server-api.types.js\";\n\ntype BrowseServerPathOptions = {\n path?: string | null;\n includeFiles?: boolean;\n};\n\ntype ServerPathBrowseErrorCode =\n | \"SERVER_PATH_NOT_FOUND\"\n | \"SERVER_PATH_NOT_DIRECTORY\"\n | \"SERVER_PATH_NOT_READABLE\";\n\nexport class ServerPathBrowseError extends Error {\n constructor(\n readonly code: ServerPathBrowseErrorCode,\n message: string,\n ) {\n super(message);\n this.name = \"ServerPathBrowseError\";\n }\n}\n\nfunction normalizeBrowsePath(path?: string | null): string {\n const trimmed = typeof path === \"string\" ? path.trim() : \"\";\n return resolve(expandHome(trimmed || homedir()));\n}\n\nfunction readRootLabel(rootPath: string): string {\n const normalized = rootPath.replace(/[\\\\/]+$/, \"\");\n return normalized || rootPath;\n}\n\nfunction buildBreadcrumbs(currentPath: string): ServerPathBreadcrumbView[] {\n const parsedPath = parse(currentPath);\n const rootPath = parsedPath.root || currentPath;\n const rootBreadcrumb: ServerPathBreadcrumbView = {\n label: readRootLabel(rootPath),\n path: rootPath,\n };\n const relativeSegments = currentPath\n .slice(rootPath.length)\n .split(/[\\\\/]+/)\n .filter(Boolean);\n\n const breadcrumbs = [rootBreadcrumb];\n let breadcrumbPath = rootPath;\n for (const segment of relativeSegments) {\n breadcrumbPath = resolve(breadcrumbPath, segment);\n breadcrumbs.push({\n label: segment,\n path: breadcrumbPath,\n });\n }\n return breadcrumbs;\n}\n\nasync function resolveEntryView(params: {\n parentPath: string;\n entryName: string;\n includeFiles: boolean;\n}): Promise<ServerPathEntryView | null> {\n const { parentPath, entryName, includeFiles } = params;\n const entryPath = resolve(parentPath, entryName);\n let entryStats;\n try {\n entryStats = await stat(entryPath);\n } catch {\n return null;\n }\n\n const isDirectory = entryStats.isDirectory();\n if (!isDirectory && !includeFiles) {\n return null;\n }\n\n return {\n name: entryName,\n path: entryPath,\n kind: isDirectory ? \"directory\" : \"file\",\n hidden: entryName.startsWith(\".\"),\n };\n}\n\nfunction sortEntryViews(left: ServerPathEntryView, right: ServerPathEntryView): number {\n if (left.kind !== right.kind) {\n return left.kind === \"directory\" ? -1 : 1;\n }\n return left.name.localeCompare(right.name);\n}\n\nexport async function browseServerPath(\n options: BrowseServerPathOptions = {},\n): Promise<ServerPathBrowseView> {\n const currentPath = normalizeBrowsePath(options.path);\n\n let currentPathStats;\n try {\n currentPathStats = await stat(currentPath);\n } catch {\n throw new ServerPathBrowseError(\n \"SERVER_PATH_NOT_FOUND\",\n \"server path does not exist\",\n );\n }\n if (!currentPathStats.isDirectory()) {\n throw new ServerPathBrowseError(\n \"SERVER_PATH_NOT_DIRECTORY\",\n \"server path must point to a directory\",\n );\n }\n\n let entryNames: string[];\n try {\n entryNames = await readdir(currentPath);\n } catch {\n throw new ServerPathBrowseError(\n \"SERVER_PATH_NOT_READABLE\",\n \"server path is not readable\",\n );\n }\n\n const entries = (\n await Promise.all(\n entryNames.map((entryName) =>\n resolveEntryView({\n parentPath: currentPath,\n entryName,\n includeFiles: options.includeFiles ?? false,\n }),\n ),\n )\n )\n .filter((entry): entry is ServerPathEntryView => entry !== null)\n .sort(sortEntryViews);\n\n const parentPath = dirname(currentPath);\n\n return {\n currentPath,\n parentPath: parentPath === currentPath ? null : parentPath,\n homePath: resolve(homedir()),\n breadcrumbs: buildBreadcrumbs(currentPath),\n entries,\n };\n}\n\nexport function isServerPathBrowseError(\n error: unknown,\n): error is ServerPathBrowseError {\n return error instanceof ServerPathBrowseError;\n}\n","import { open, stat } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { extname, resolve } from \"node:path\";\nimport { expandHome } from \"@nextclaw/core\";\nimport type { ServerPathReadView } from \"@nextclaw-server/shared/types/server-api.types.js\";\n\ntype ReadServerPathOptions = {\n path?: string | null;\n basePath?: string | null;\n maxBytes?: number;\n};\n\ntype ServerPathReadErrorCode =\n | \"SERVER_PATH_BASE_REQUIRED\"\n | \"SERVER_PATH_NOT_FOUND\"\n | \"SERVER_PATH_NOT_FILE\"\n | \"SERVER_PATH_NOT_READABLE\";\n\nconst DEFAULT_PREVIEW_MAX_BYTES = 200_000;\nconst MARKDOWN_EXTENSIONS = new Set([\".md\", \".mdx\", \".markdown\"]);\nconst TEXT_EXTENSIONS = new Set([\n \".c\",\n \".cc\",\n \".conf\",\n \".cpp\",\n \".css\",\n \".csv\",\n \".env\",\n \".go\",\n \".graphql\",\n \".h\",\n \".hpp\",\n \".html\",\n \".ini\",\n \".java\",\n \".js\",\n \".json\",\n \".jsx\",\n \".log\",\n \".mjs\",\n \".py\",\n \".rb\",\n \".rs\",\n \".sh\",\n \".sql\",\n \".svg\",\n \".toml\",\n \".ts\",\n \".tsx\",\n \".txt\",\n \".xml\",\n \".yaml\",\n \".yml\",\n]);\n\nexport class ServerPathReadError extends Error {\n constructor(\n readonly code: ServerPathReadErrorCode,\n message: string,\n ) {\n super(message);\n this.name = \"ServerPathReadError\";\n }\n}\n\nfunction normalizeReadPath(params: {\n path?: string | null;\n basePath?: string | null;\n}): string {\n const { basePath, path } = params;\n const rawPath = typeof path === \"string\" ? path.trim() : \"\";\n const normalizedBasePath =\n typeof basePath === \"string\" ? basePath.trim() : \"\";\n if (!rawPath) {\n return resolve(expandHome(normalizedBasePath || homedir()));\n }\n const expandedPath = expandHome(rawPath);\n if (expandedPath.startsWith(\"/\")) {\n return resolve(expandedPath);\n }\n if (!normalizedBasePath) {\n throw new ServerPathReadError(\n \"SERVER_PATH_BASE_REQUIRED\",\n \"relative server path requires a base path\",\n );\n }\n const resolvedBasePath = expandHome(normalizedBasePath);\n return resolve(resolvedBasePath, expandedPath);\n}\n\nfunction inferPreviewKind(path: string): \"markdown\" | \"text\" | \"binary\" {\n const extension = extname(path).toLowerCase();\n if (MARKDOWN_EXTENSIONS.has(extension)) {\n return \"markdown\";\n }\n if (TEXT_EXTENSIONS.has(extension)) {\n return \"text\";\n }\n return \"binary\";\n}\n\nfunction isLikelyTextBuffer(buffer: Buffer): boolean {\n for (const byte of buffer) {\n if (byte === 0) {\n return false;\n }\n }\n return true;\n}\n\nfunction readLanguageHint(path: string): string | null {\n const extension = extname(path).toLowerCase();\n if (!extension) {\n return null;\n }\n if (MARKDOWN_EXTENSIONS.has(extension)) {\n return \"markdown\";\n }\n return extension.slice(1) || null;\n}\n\nasync function readFilePreviewBytes(params: {\n resolvedPath: string;\n sizeBytes: number;\n maxBytes: number;\n}): Promise<{ buffer: Buffer; truncated: boolean }> {\n const { maxBytes, resolvedPath, sizeBytes } = params;\n const bytesToRead = Math.min(sizeBytes, maxBytes);\n const fileHandle = await open(resolvedPath, \"r\");\n try {\n const buffer = Buffer.alloc(bytesToRead);\n const { bytesRead } = await fileHandle.read(buffer, 0, bytesToRead, 0);\n return {\n buffer: buffer.subarray(0, bytesRead),\n truncated: sizeBytes > maxBytes,\n };\n } finally {\n await fileHandle.close();\n }\n}\n\nexport async function readServerPath(\n options: ReadServerPathOptions = {},\n): Promise<ServerPathReadView> {\n const requestedPath = typeof options.path === \"string\" ? options.path.trim() : \"\";\n const resolvedPath = normalizeReadPath(options);\n\n let resolvedStats;\n try {\n resolvedStats = await stat(resolvedPath);\n } catch {\n throw new ServerPathReadError(\n \"SERVER_PATH_NOT_FOUND\",\n \"server path does not exist\",\n );\n }\n if (!resolvedStats.isFile()) {\n throw new ServerPathReadError(\n \"SERVER_PATH_NOT_FILE\",\n \"server path must point to a file\",\n );\n }\n\n let previewBytes;\n try {\n previewBytes = await readFilePreviewBytes({\n resolvedPath,\n sizeBytes: resolvedStats.size,\n maxBytes: options.maxBytes ?? DEFAULT_PREVIEW_MAX_BYTES,\n });\n } catch {\n throw new ServerPathReadError(\n \"SERVER_PATH_NOT_READABLE\",\n \"server path is not readable\",\n );\n }\n\n const inferredKind = inferPreviewKind(resolvedPath);\n const resolvedKind =\n inferredKind === \"binary\" && isLikelyTextBuffer(previewBytes.buffer)\n ? \"text\"\n : inferredKind;\n\n if (resolvedKind === \"binary\") {\n return {\n requestedPath: requestedPath || resolvedPath,\n resolvedPath,\n kind: \"binary\",\n sizeBytes: resolvedStats.size,\n truncated: previewBytes.truncated,\n languageHint: readLanguageHint(resolvedPath),\n };\n }\n\n return {\n requestedPath: requestedPath || resolvedPath,\n resolvedPath,\n kind: resolvedKind,\n sizeBytes: resolvedStats.size,\n truncated: previewBytes.truncated,\n text: previewBytes.buffer.toString(\"utf8\"),\n languageHint: readLanguageHint(resolvedPath),\n };\n}\n\nexport function isServerPathReadError(\n error: unknown,\n): error is ServerPathReadError {\n return error instanceof ServerPathReadError;\n}\n","import type { Context } from \"hono\";\nimport type { ServerPathBrowseView, ServerPathReadView } from \"@nextclaw-server/shared/types/server-api.types.js\";\nimport {\n browseServerPath,\n isServerPathBrowseError,\n} from \"@nextclaw-server/features/server-path/utils/server-path-browse.utils.js\";\nimport {\n isServerPathReadError,\n readServerPath,\n} from \"@nextclaw-server/features/server-path/utils/server-path-read.utils.js\";\nimport { err, ok } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\n\nfunction readIncludeFilesFlag(value: string | undefined): boolean {\n return value === \"1\" || value === \"true\";\n}\n\nexport class ServerPathRoutesController {\n readonly browse = async (c: Context) => {\n try {\n const payload: ServerPathBrowseView = await browseServerPath({\n path: c.req.query(\"path\"),\n includeFiles: readIncludeFilesFlag(c.req.query(\"includeFiles\")),\n });\n return c.json(ok(payload));\n } catch (error) {\n if (isServerPathBrowseError(error)) {\n return c.json(err(error.code, error.message), 400);\n }\n throw error;\n }\n };\n\n readonly read = async (c: Context) => {\n try {\n const payload: ServerPathReadView = await readServerPath({\n path: c.req.query(\"path\"),\n basePath: c.req.query(\"basePath\"),\n });\n return c.json(ok(payload));\n } catch (error) {\n if (isServerPathReadError(error)) {\n return c.json(err(error.code, error.message), 400);\n }\n throw error;\n }\n };\n}\n","import { Hono, type Handler } from \"hono\";\nimport type {\n NcpMessageAbortPayload,\n NcpRunHandle,\n NcpStreamRequestPayload,\n} from \"@nextclaw/ncp\";\nimport { AccessManager } from \"@nextclaw/kernel\";\nimport {\n ingressKeys,\n type AgentRunSendIngressPayload,\n type IngressEnvelope,\n} from \"@nextclaw/shared\";\nimport { AgentsRoutesController } from \"@nextclaw-server/features/agents/index.js\";\nimport { AppRoutesController } from \"@nextclaw-server/app/controllers/app.controller.js\";\nimport { AuthRoutesController, UiAuthService } from \"@nextclaw-server/features/auth/index.js\";\nimport { ConfigRoutesController } from \"@nextclaw-server/features/config/index.js\";\nimport { CronRoutesController } from \"@nextclaw-server/features/cron/index.js\";\nimport { NcpAssetRoutesController } from \"@nextclaw-server/features/attachments/index.js\";\nimport { NcpSessionRoutesController } from \"@nextclaw-server/features/sessions/index.js\";\nimport {\n McpMarketplaceController,\n mountMarketplaceRoutes,\n normalizeMarketplaceBaseUrl,\n SkillMarketplaceController\n} from \"@nextclaw-server/features/marketplace/index.js\";\nimport { RemoteRoutesController } from \"@nextclaw-server/features/remote-access/index.js\";\nimport { RuntimeControlRoutesController } from \"@nextclaw-server/features/runtime-control/index.js\";\nimport { RuntimeUpdateRoutesController } from \"@nextclaw-server/features/runtime-update/index.js\";\nimport { PanelAppsRoutesController } from \"@nextclaw-server/features/panel-apps/index.js\";\nimport { PreferencesRoutesController } from \"@nextclaw-server/features/preferences/index.js\";\nimport { ServiceAppsRoutesController } from \"@nextclaw-server/features/service-apps/index.js\";\nimport { err, ok, readJson } from \"@nextclaw-server/shared/utils/http-response.utils.js\";\nimport { createNcpSessionEventStreamResponse } from \"@nextclaw-server/app/utils/ncp-session-event-stream.utils.js\";\nimport { ServerPathRoutesController } from \"@nextclaw-server/features/server-path/index.js\";\nimport type { UiRouterOptions } from \"@nextclaw-server/app/types/router-options.types.js\";\n\nconst NCP_AGENT_BASE_PATH = \"/api/ncp/agent\";\nconst AGENT_RUNS_BASE_PATH = \"/api/agent-runs\";\n\nfunction createUiRouteControllers(\n options: UiRouterOptions,\n authService: UiAuthService,\n marketplaceBaseUrl: string\n) {\n const {\n kernel,\n panelAppClientSdkScript,\n remoteAccess,\n runtimeControl,\n runtimeUpdate,\n } = options;\n return {\n app: new AppRoutesController(options),\n agents: new AgentsRoutesController(options),\n auth: new AuthRoutesController(authService),\n config: new ConfigRoutesController(options),\n cron: new CronRoutesController(options),\n ncpSession: new NcpSessionRoutesController(options),\n ncpAsset: new NcpAssetRoutesController(options),\n panelApps: new PanelAppsRoutesController(kernel.panelAppManager, {\n panelAppClientSdkScript,\n }),\n preferences: new PreferencesRoutesController(kernel.preferenceManager),\n serviceApps: new ServiceAppsRoutesController({\n panelAppManager: kernel.panelAppManager,\n serviceAppManager: kernel.serviceAppManager,\n }),\n serverPath: new ServerPathRoutesController(),\n remote: remoteAccess ? new RemoteRoutesController(remoteAccess) : null,\n runtimeControl: runtimeControl ? new RuntimeControlRoutesController(runtimeControl) : null,\n runtimeUpdate: runtimeUpdate ? new RuntimeUpdateRoutesController(runtimeUpdate) : null,\n skillMarketplace: new SkillMarketplaceController(options, marketplaceBaseUrl),\n mcpMarketplace: new McpMarketplaceController(options, marketplaceBaseUrl)\n };\n}\n\ntype UiRouteControllers = ReturnType<typeof createUiRouteControllers>;\ntype HttpMethod = \"delete\" | \"get\" | \"patch\" | \"post\" | \"put\";\ntype RouteDefinition = readonly [HttpMethod, string, Handler];\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction hasOwn(value: Record<string, unknown>, key: string): boolean {\n return Object.prototype.hasOwnProperty.call(value, key);\n}\n\nfunction isValidSendEnvelope(value: unknown): value is AgentRunSendIngressPayload {\n if (!isRecord(value)) {\n return false;\n }\n const sessionId = readOptionalSendIdentity(value, \"sessionId\");\n const peerId = readOptionalSendIdentity(value, \"peerId\");\n if (sessionId === null || peerId === null || (sessionId && peerId)) {\n return false;\n }\n const hasMessage = hasOwn(value, \"message\");\n const hasContent = hasOwn(value, \"content\");\n if (hasMessage === hasContent) {\n return false;\n }\n return hasMessage ? isRecord(value.message) : Array.isArray(value.content);\n}\n\nfunction readOptionalSendIdentity(\n value: Record<string, unknown>,\n key: \"peerId\" | \"sessionId\",\n): string | null | undefined {\n if (!hasOwn(value, key)) {\n return undefined;\n }\n const raw = value[key];\n if (typeof raw !== \"string\") {\n return null;\n }\n const trimmed = raw.trim();\n return trimmed || null;\n}\n\nfunction readStreamPayload(url: string): NcpStreamRequestPayload | null {\n const sessionId = new URL(url).searchParams.get(\"sessionId\")?.trim();\n return sessionId ? { sessionId } : null;\n}\n\nfunction isAbortPayload(value: unknown): value is NcpMessageAbortPayload {\n return isRecord(value) && typeof value.sessionId === \"string\" && value.sessionId.trim().length > 0;\n}\n\nclass UiRouteRegistry {\n constructor(\n private readonly app: Hono,\n private readonly options: UiRouterOptions,\n private readonly controllers: UiRouteControllers,\n ) {}\n\n private readonly mountRoutes = (routes: readonly RouteDefinition[]): void => {\n for (const [method, path, handler] of routes) {\n this.app[method](path, handler);\n }\n };\n\n private readonly mountAgentRunRoutes = (\n basePath: string,\n kernel: UiRouterOptions[\"kernel\"],\n ): void => {\n this.app.post(`${basePath}/send`, async (c) => {\n const body = await readJson<AgentRunSendIngressPayload>(c.req.raw);\n if (!body.ok || !isValidSendEnvelope(body.data)) {\n return c.json(err(\"INVALID_BODY\", \"Invalid NCP request envelope.\"), 400);\n }\n const handle = await kernel.ingress.handle<AgentRunSendIngressPayload, NcpRunHandle>(\n {\n type: ingressKeys.agentRun.send,\n payload: body.data,\n },\n { source: \"ui-http\" },\n );\n return c.json(ok(handle));\n });\n this.app.get(`${basePath}/stream`, (c) => {\n const payload = readStreamPayload(c.req.raw.url);\n if (!payload) {\n return c.json(err(\"INVALID_QUERY\", \"sessionId is required.\"), 400);\n }\n return createNcpSessionEventStreamResponse(kernel.eventBus, payload, c.req.raw.signal);\n });\n this.app.post(`${basePath}/abort`, async (c) => {\n const body = await readJson<NcpMessageAbortPayload>(c.req.raw);\n if (!body.ok || !isAbortPayload(body.data)) {\n return c.json(err(\"INVALID_BODY\", \"sessionId is required.\"), 400);\n }\n await kernel.ingress.handle<NcpMessageAbortPayload, void>(\n {\n type: ingressKeys.agentRun.abort,\n payload: body.data,\n },\n { source: \"ui-http\" },\n );\n return c.json(ok({ accepted: true }));\n });\n };\n\n private readonly mountNcpAgentRoutes = (\n kernel: UiRouterOptions[\"kernel\"],\n ncpAsset: UiRouteControllers[\"ncpAsset\"],\n ): void => {\n this.mountAgentRunRoutes(NCP_AGENT_BASE_PATH, kernel);\n this.mountRoutes([\n [\"post\", \"/api/ncp/assets\", ncpAsset.putAssets],\n [\"get\", \"/api/ncp/assets/content\", ncpAsset.getAssetContent],\n ]);\n };\n\n private readonly mountResourceRoutes = (): void => {\n const {\n ncpSession,\n panelApps,\n preferences,\n serviceApps,\n serverPath,\n } = this.controllers;\n this.mountRoutes([\n [\"get\", \"/api/ncp/session-types\", ncpSession.getSessionTypes],\n [\"get\", \"/api/ncp/sessions\", ncpSession.listSessions],\n [\"get\", \"/api/ncp/sessions/:sessionId\", ncpSession.getSession],\n [\"put\", \"/api/ncp/sessions/:sessionId\", ncpSession.patchSession],\n [\"get\", \"/api/ncp/sessions/:sessionId/messages\", ncpSession.listSessionMessages],\n [\"get\", \"/api/ncp/sessions/:sessionId/skills\", ncpSession.getSessionSkills],\n [\"delete\", \"/api/ncp/sessions/:sessionId\", ncpSession.deleteSession],\n [\"get\", \"/api/panel-apps\", panelApps.list],\n [\"get\", \"/api/panel-app-bridge.js\", panelApps.getPanelAppBridgeScript],\n [\"get\", \"/api/panel-app-client-sdk.js\", panelApps.getPanelAppClientSdkScript],\n [\"post\", \"/api/panel-app-bridge-sessions\", panelApps.createBridgeSession],\n [\"delete\", \"/api/panel-app-bridge-sessions/:token\", panelApps.deleteBridgeSession],\n [\"post\", \"/api/panel-app-client-grants/:appId\", panelApps.grantClient],\n [\"delete\", \"/api/panel-app-client-grants/:appId\", panelApps.revokeClient],\n [\"post\", \"/api/panel-app-agent/send\", panelApps.sendAgentMessage],\n [\"post\", \"/api/panel-app-agent/generate-object\", panelApps.generateAgentObject],\n [\"post\", \"/api/panel-app-agent-capabilities/:capability/grant\", panelApps.grantAgentCapability],\n [\"patch\", \"/api/panel-apps/:id/preferences\", panelApps.updatePanelAppPreferences],\n [\"get\", \"/api/preferences/:key\", preferences.get],\n [\"put\", \"/api/preferences/:key\", preferences.update],\n [\"delete\", \"/api/preferences/:key\", preferences.delete],\n [\"delete\", \"/api/panel-apps/:id\", panelApps.deletePanelApp],\n [\"post\", \"/api/panel-apps/:id/open\", panelApps.recordPanelAppOpened],\n [\"get\", \"/api/panel-apps/:id/content\", panelApps.getPanelAppContent],\n [\"get\", \"/api/panel-apps/:id/assets/*\", panelApps.getPanelAppAsset],\n [\"get\", \"/api/panel-app-assets/:token/*\", panelApps.getPanelAppAssetByToken],\n [\"get\", \"/api/service-apps\", serviceApps.listServiceApps],\n [\"post\", \"/api/service-apps/:appId/restart\", serviceApps.restartServiceApp],\n [\"post\", \"/api/service-apps/:appId/actions/discover\", serviceApps.discoverServiceAppActions],\n [\"get\", \"/api/service-apps/:appId\", serviceApps.getServiceApp],\n [\"delete\", \"/api/service-apps/:appId\", serviceApps.deleteServiceApp],\n [\"get\", \"/api/service-actions\", serviceApps.listServiceActions],\n [\"post\", \"/api/service-actions/:actionId/invoke\", serviceApps.invokeServiceAction],\n [\"post\", \"/api/service-actions/:actionId/grant\", serviceApps.grantServiceAction],\n [\"delete\", \"/api/service-actions/:actionId/grant\", serviceApps.revokeServiceAction],\n [\"get\", \"/api/service-action-grants\", serviceApps.listServiceActionGrants],\n [\"post\", \"/api/service-action-grants\", serviceApps.grantServiceActions],\n [\"delete\", \"/api/service-action-grants/:actionId\", serviceApps.revokeServiceActionGrant],\n [\"get\", \"/api/server-paths/browse\", serverPath.browse],\n [\"get\", \"/api/server-paths/read\", serverPath.read],\n ]);\n };\n\n readonly register = (): void => {\n const {\n agents,\n app,\n auth,\n config,\n cron,\n ncpAsset,\n remote,\n runtimeControl,\n runtimeUpdate,\n } = this.controllers;\n this.mountRoutes([\n [\"get\", \"/api/health\", app.health],\n [\"get\", \"/api/app/meta\", app.appMeta],\n [\"get\", \"/api/runtime/bootstrap-status\", app.bootstrapStatus],\n [\"get\", \"/api/auth/status\", auth.getStatus],\n [\"post\", \"/api/auth/setup\", auth.setup],\n [\"post\", \"/api/auth/login\", auth.login],\n [\"post\", \"/api/auth/logout\", auth.logout],\n [\"put\", \"/api/auth/password\", auth.updatePassword],\n [\"put\", \"/api/auth/enabled\", auth.updateEnabled],\n [\"post\", \"/api/auth/bridge\", auth.issueBridgeSession],\n [\"get\", \"/api/agents\", agents.listAgents],\n [\"post\", \"/api/agents\", agents.createAgent],\n [\"put\", \"/api/agents/:agentId\", agents.updateAgent],\n [\"delete\", \"/api/agents/:agentId\", agents.deleteAgent],\n [\"get\", \"/api/agents/:agentId/avatar\", agents.getAgentAvatar],\n ]);\n this.mountRoutes([\n [\"get\", \"/api/config\", config.getConfig],\n [\"get\", \"/api/config/meta\", config.getConfigMeta],\n [\"get\", \"/api/config/schema\", config.getConfigSchema],\n [\"get\", \"/api/providers\", config.listProviders],\n [\"get\", \"/api/provider-templates\", config.listProviderTemplates],\n [\"post\", \"/api/providers\", config.createProvider],\n [\"put\", \"/api/providers/:providerId\", config.updateProvider],\n [\"delete\", \"/api/providers/:providerId\", config.deleteProvider],\n [\"post\", \"/api/providers/:providerId/test\", config.testProviderConnection],\n [\"post\", \"/api/providers/:providerId/auth/start\", config.startProviderAuth],\n [\"post\", \"/api/providers/:providerId/auth/poll\", config.pollProviderAuth],\n [\"post\", \"/api/providers/:providerId/auth/import-cli\", config.importProviderAuthFromCli],\n [\"put\", \"/api/config/model\", config.updateConfigModel],\n [\"put\", \"/api/config/search\", config.updateConfigSearch],\n [\"put\", \"/api/config/channels/:channel\", config.updateChannel],\n [\"post\", \"/api/config/channels/:channel/auth/start\", config.startChannelAuth],\n [\"post\", \"/api/config/channels/:channel/auth/connect\", config.connectChannelAuth],\n [\"post\", \"/api/config/channels/:channel/auth/poll\", config.pollChannelAuth],\n [\"put\", \"/api/config/secrets\", config.updateSecrets],\n [\"put\", \"/api/config/runtime\", config.updateRuntime],\n [\"post\", \"/api/config/actions/:actionId/execute\", config.executeAction],\n ]);\n this.mountResourceRoutes();\n this.mountAgentRunRoutes(AGENT_RUNS_BASE_PATH, this.options.kernel);\n this.mountNcpAgentRoutes(this.options.kernel, ncpAsset);\n this.mountRoutes([\n [\"get\", \"/api/cron\", cron.listJobs],\n [\"post\", \"/api/cron\", cron.createJob],\n [\"delete\", \"/api/cron/:id\", cron.deleteJob],\n [\"put\", \"/api/cron/:id/enable\", cron.enableJob],\n [\"post\", \"/api/cron/:id/run\", cron.runJob],\n ]);\n if (remote) {\n this.mountRoutes([\n [\"get\", \"/api/remote/status\", remote.getStatus],\n [\"get\", \"/api/remote/doctor\", remote.getDoctor],\n [\"post\", \"/api/remote/login\", remote.login],\n [\"post\", \"/api/remote/auth/start\", remote.startBrowserAuth],\n [\"post\", \"/api/remote/auth/poll\", remote.pollBrowserAuth],\n [\"post\", \"/api/remote/logout\", remote.logout],\n [\"put\", \"/api/remote/account/profile\", remote.updateProfile],\n [\"put\", \"/api/remote/settings\", remote.updateSettings],\n [\"post\", \"/api/remote/service/:action\", remote.controlService],\n ]);\n }\n if (runtimeControl) {\n this.mountRoutes([\n [\"get\", \"/api/runtime/control\", runtimeControl.getControl],\n [\"post\", \"/api/runtime/control/start-service\", runtimeControl.startService],\n [\"post\", \"/api/runtime/control/restart-service\", runtimeControl.restartService],\n [\"post\", \"/api/runtime/control/stop-service\", runtimeControl.stopService],\n ]);\n }\n if (runtimeUpdate) {\n this.mountRoutes([\n [\"get\", \"/api/runtime/update\", runtimeUpdate.getState],\n [\"post\", \"/api/runtime/update/check\", runtimeUpdate.checkForUpdates],\n [\"post\", \"/api/runtime/update/download\", runtimeUpdate.downloadUpdate],\n [\"post\", \"/api/runtime/update/apply\", runtimeUpdate.applyDownloadedUpdate],\n [\"put\", \"/api/runtime/update/preferences\", runtimeUpdate.updatePreferences],\n [\"put\", \"/api/runtime/update/channel\", runtimeUpdate.updateChannel],\n ]);\n }\n this.app.post(\"/webhook\", async (c) => {\n const ingress = this.options.kernel.ingress;\n const body = await readJson<IngressEnvelope>(c.req.raw);\n if (!body.ok) {\n return c.json(err(\"INVALID_BODY\", \"invalid ingress body\"), 400);\n }\n try {\n const result = await ingress.handle(body.data, {\n source: \"webhook\",\n token: /^Bearer\\s+(.+)$/i.exec(c.req.raw.headers.get(\"authorization\")?.trim() ?? \"\")?.[1]?.trim() || null,\n });\n return c.json(ok(result ?? { accepted: true }));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n const status = message.toLowerCase().includes(\"unauthorized\") ? 401 : 400;\n return c.json(err(\"WEBHOOK_FAILED\", message), status);\n }\n });\n mountMarketplaceRoutes(this.app, {\n skill: this.controllers.skillMarketplace,\n mcp: this.controllers.mcpMarketplace\n });\n };\n}\n\nexport function createUiRouter(options: UiRouterOptions, authServiceOverride?: UiAuthService): Hono {\n const app = new Hono();\n const marketplaceBaseUrl = normalizeMarketplaceBaseUrl(options);\n const authService = authServiceOverride ?? options.authService ?? new UiAuthService(\n options.kernel.accessManager ?? new AccessManager({ configPath: options.configPath }),\n );\n const controllers = createUiRouteControllers(options, authService, marketplaceBaseUrl);\n\n app.notFound((c) => c.json(err(\"NOT_FOUND\", \"endpoint not found\"), 404));\n\n app.use(\"/api/*\", async (c, next) => {\n const path = c.req.path;\n if (\n path === \"/api/health\" ||\n path === \"/api/runtime/bootstrap-status\" ||\n path.startsWith(\"/api/auth/\") ||\n path.startsWith(\"/api/panel-app-assets/\")\n ) {\n await next();\n return;\n }\n if (!authService.isProtectionEnabled() || authService.isRequestAuthenticated(c.req.raw)) {\n await next();\n return;\n }\n c.status(401);\n return c.json(err(\"UNAUTHORIZED\", \"Authentication required.\"), 401);\n });\n\n new UiRouteRegistry(app, options, controllers).register();\n\n return app;\n}\n","import { Hono } from \"hono\";\nimport { compress } from \"hono/compress\";\nimport { serve } from \"@hono/node-server\";\nimport { AccessManager } from \"@nextclaw/kernel\";\nimport { WebSocketServer } from \"ws\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { readFile, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { Server } from \"node:http\";\nimport { UiAuthService } from \"@nextclaw-server/features/auth/index.js\";\nimport {\n EventStreamAuthService,\n EventStreamClientRegistry,\n} from \"@nextclaw-server/features/event-stream/index.js\";\nimport { createUiRouter } from \"./router.js\";\nimport type { UiRouterOptions } from \"@nextclaw-server/app/types/router-options.types.js\";\nimport { serveStatic } from \"hono/serve-static\";\n\nexport type UiServerHandle = {\n host: string;\n port: number;\n close: () => Promise<void>;\n};\n\nconst DEFAULT_CORS_ORIGINS = (origin: string | undefined | null) => {\n if (!origin) {\n return undefined;\n }\n if (origin.startsWith(\"http://localhost:\") || origin.startsWith(\"http://127.0.0.1:\")) {\n return origin;\n }\n return undefined;\n};\n\nconst DEFAULT_ALLOWED_CORS_HEADERS = \"Content-Type, Authorization\";\nconst DEFAULT_ALLOWED_CORS_METHODS = \"GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS\";\nconst NULL_ORIGIN = \"null\";\nconst PANEL_APP_RUNTIME_TOKEN_HEADER = \"x-nextclaw-panel-bridge-session\";\nconst STALE_UI_ASSET_RELOAD_MODULE = \"globalThis.location?.reload();\\nexport {};\\n\";\ntype CorsPolicy = string[] | \"*\" | typeof DEFAULT_CORS_ORIGINS;\n\nfunction buildVaryHeader(current: string | null, value: string): string {\n if (!current) {\n return value;\n }\n const values = current\n .split(\",\")\n .map((item) => item.trim())\n .filter(Boolean);\n if (!values.includes(value)) {\n return [...values, value].join(\", \");\n }\n return values.join(\", \");\n}\n\nfunction resolveAllowedCorsOrigin(\n requestOrigin: string | null,\n policy: CorsPolicy\n): string | null {\n if (!requestOrigin) {\n return null;\n }\n if (policy === \"*\") {\n return requestOrigin;\n }\n if (Array.isArray(policy)) {\n return policy.includes(requestOrigin) ? requestOrigin : null;\n }\n return policy(requestOrigin) ?? null;\n}\n\nfunction createCorsHeaders(allowOrigin: string, allowHeaders?: string | null, currentVary?: string | null): Headers {\n const headers = new Headers();\n headers.set(\"Access-Control-Allow-Origin\", allowOrigin);\n headers.set(\"Access-Control-Allow-Credentials\", \"true\");\n headers.set(\"Access-Control-Allow-Methods\", DEFAULT_ALLOWED_CORS_METHODS);\n headers.set(\n \"Access-Control-Allow-Headers\",\n allowHeaders?.trim() || DEFAULT_ALLOWED_CORS_HEADERS\n );\n const varyWithOrigin = buildVaryHeader(currentVary ?? null, \"Origin\");\n headers.set(\"Vary\", buildVaryHeader(varyWithOrigin, \"Access-Control-Request-Headers\"));\n return headers;\n}\n\nfunction readRequestedHeaderNames(value: string | null): string[] {\n return (value ?? \"\")\n .split(\",\")\n .map((header) => header.trim().toLowerCase())\n .filter(Boolean);\n}\n\nfunction isPanelAppPublicBrowserResource(path: string): boolean {\n return path === \"/api/panel-app-client-sdk.js\" ||\n path.startsWith(\"/api/panel-app-assets/\") ||\n (/^\\/api\\/panel-apps\\/[^/]+\\/content$/.test(path));\n}\n\nfunction isPanelAppRuntimePreflight(origin: string | null, allowHeaders: string | null): boolean {\n return origin === NULL_ORIGIN && readRequestedHeaderNames(allowHeaders).includes(PANEL_APP_RUNTIME_TOKEN_HEADER);\n}\n\nfunction isValidPanelAppRuntimeRequest(gateway: UiRouterOptions, request: Request): boolean {\n const token = request.headers.get(PANEL_APP_RUNTIME_TOKEN_HEADER)?.trim();\n if (!token) {\n return false;\n }\n try {\n gateway.kernel.panelAppManager.resolvePanelAppBridgeSession(token);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction mountUiStaticAssets(app: Hono, staticDir: string): void {\n if (!existsSync(join(staticDir, \"index.html\"))) {\n return;\n }\n\n const indexHtml = readFileSync(join(staticDir, \"index.html\"), \"utf-8\");\n app.use(\n \"/*\",\n serveStatic({\n root: staticDir,\n join,\n getContent: async (path) => {\n try {\n return await readFile(path);\n } catch {\n return null;\n }\n },\n isDir: async (path) => {\n try {\n return (await stat(path)).isDirectory();\n } catch {\n return false;\n }\n },\n onFound: (_, c) => {\n c.header(\"cache-control\", \"no-store\");\n }\n })\n );\n app.get(\"/assets/*\", (c) => {\n if (!c.req.path.endsWith(\".js\")) {\n return c.notFound();\n }\n return c.body(STALE_UI_ASSET_RELOAD_MODULE, 200, {\n \"content-type\": \"application/javascript; charset=utf-8\",\n \"cache-control\": \"no-store\"\n });\n });\n app.get(\"*\", (c) => {\n const path = c.req.path;\n if (path.startsWith(\"/api\") || path.startsWith(\"/ws\") || path.startsWith(\"/_remote\") || path.startsWith(\"/webhook\")) {\n return c.notFound();\n }\n return c.html(indexHtml, 200, { \"cache-control\": \"no-store\" });\n });\n}\n\nfunction attachUiSocketServer(\n httpServer: Server,\n eventStreamAuth: EventStreamAuthService,\n eventStreamClients: EventStreamClientRegistry,\n): WebSocketServer {\n const wss = new WebSocketServer({ noServer: true });\n httpServer.on(\"upgrade\", (request, socket, head) => {\n const host = request.headers.host ?? \"127.0.0.1\";\n const url = request.url ?? \"/\";\n const pathname = new URL(url, `http://${host}`).pathname;\n if (pathname !== \"/ws\") {\n return;\n }\n const principal = eventStreamAuth.authenticate(request);\n if (!principal) {\n socket.write(\"HTTP/1.1 401 Unauthorized\\r\\nConnection: close\\r\\n\\r\\n\");\n socket.destroy();\n return;\n }\n wss.handleUpgrade(request, socket, head, (ws) => {\n eventStreamClients.add(ws, principal);\n wss.emit(\"connection\", ws, request);\n });\n });\n return wss;\n}\n\nexport async function startUiServer(gateway: UiRouterOptions): Promise<UiServerHandle> {\n const {\n corsOrigins,\n uiStaticDir,\n } = gateway;\n const uiConfig = gateway.uiConfig;\n if (!uiConfig) {\n throw new Error(\"uiConfig is required to start UI server\");\n }\n const { host, port } = uiConfig;\n const app = new Hono();\n app.use(\"/*\", compress());\n const corsPolicy = corsOrigins ?? DEFAULT_CORS_ORIGINS;\n const authService = new UiAuthService(\n gateway.kernel.accessManager ?? new AccessManager({ configPath: gateway.configPath }),\n );\n app.use(\"/api/*\", async (c, next) => {\n const origin = c.req.header(\"origin\")?.trim() ?? null;\n const path = c.req.path;\n const allowOrigin = resolveAllowedCorsOrigin(origin, corsPolicy);\n const allowHeaders = c.req.header(\"access-control-request-headers\")?.trim() ?? null;\n const isPanelAppRuntimeCors = isPanelAppRuntimePreflight(origin, allowHeaders) ||\n (origin === NULL_ORIGIN && isValidPanelAppRuntimeRequest(gateway, c.req.raw));\n\n if (c.req.method === \"OPTIONS\") {\n if (allowOrigin) {\n const headers = createCorsHeaders(allowOrigin, allowHeaders);\n return new Response(null, { status: 204, headers });\n }\n if (isPanelAppRuntimePreflight(origin, allowHeaders)) {\n const headers = createCorsHeaders(NULL_ORIGIN, allowHeaders);\n return new Response(null, { status: 204, headers });\n }\n return new Response(null, { status: 204 });\n }\n\n if (\n origin === NULL_ORIGIN &&\n !allowOrigin &&\n !isPanelAppRuntimeCors &&\n !isPanelAppPublicBrowserResource(path)\n ) {\n return new Response(\"Panel App runtime token is required.\", {\n status: 401,\n headers: { \"content-type\": \"text/plain; charset=utf-8\" },\n });\n }\n\n await next();\n\n const resolvedAllowOrigin = allowOrigin ?? (isPanelAppRuntimeCors ? NULL_ORIGIN : null);\n if (resolvedAllowOrigin) {\n for (const [name, value] of createCorsHeaders(resolvedAllowOrigin, allowHeaders, c.res.headers.get(\"Vary\"))) {\n c.res.headers.set(name, value);\n }\n }\n });\n\n const eventStreamAuth = new EventStreamAuthService({\n uiAuth: authService,\n extensionAuth: gateway.extensions,\n getChannelBindings: gateway.extensions?.getChannelBindings,\n });\n const eventStreamClients = new EventStreamClientRegistry();\n const unsubscribeEventBus = gateway.appEventBus.subscribeAll(eventStreamClients.publish);\n\n app.route(\n \"/\",\n createUiRouter(gateway, authService)\n );\n\n if (uiStaticDir) {\n mountUiStaticAssets(app, uiStaticDir);\n }\n\n const server = await new Promise<Server>((resolve, reject) => {\n const httpServer = serve(\n {\n fetch: app.fetch,\n port,\n hostname: host\n },\n () => resolve(httpServer as unknown as Server)\n ) as unknown as Server;\n httpServer.once(\"error\", reject);\n });\n\n const httpServer = server as unknown as Server;\n const wss = attachUiSocketServer(httpServer, eventStreamAuth, eventStreamClients);\n\n return {\n host,\n port,\n close: () =>\n new Promise((resolve) => {\n unsubscribeEventBus();\n eventStreamClients.closeAll();\n wss.close(() => {\n server.close(() => resolve());\n });\n })\n };\n}\n"],"mappings":"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"}